summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2023-07-20 19:01:12 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2023-07-20 19:01:12 +0700
commite5d77a0741bcc55088054b2ad4a91ab0508ac092 (patch)
tree816fc0d1139945ee9bfd22ca40f1e570e816a02f
parentRefactoring in Asn1.Crmf (diff)
downloadBouncyCastle.NET-ed25519-e5d77a0741bcc55088054b2ad4a91ab0508ac092.tar.xz
Refactoring in Asn1.Cms
-rw-r--r--crypto/src/asn1/cms/Attribute.cs34
-rw-r--r--crypto/src/asn1/cms/Attributes.cs4
-rw-r--r--crypto/src/asn1/cms/AuthEnvelopedData.cs56
-rw-r--r--crypto/src/asn1/cms/AuthenticatedData.cs59
-rw-r--r--crypto/src/asn1/cms/CcmParameters.cs8
-rw-r--r--crypto/src/asn1/cms/CmsAlgorithmProtection.cs23
-rw-r--r--crypto/src/asn1/cms/CompressedData.cs53
-rw-r--r--crypto/src/asn1/cms/ContentInfo.cs25
-rw-r--r--crypto/src/asn1/cms/EncryptedContentInfo.cs35
-rw-r--r--crypto/src/asn1/cms/EncryptedData.cs32
-rw-r--r--crypto/src/asn1/cms/EnvelopedData.cs48
-rw-r--r--crypto/src/asn1/cms/GcmParameters.cs8
-rw-r--r--crypto/src/asn1/cms/IssuerAndSerialNumber.cs53
-rw-r--r--crypto/src/asn1/cms/KEKIdentifier.cs52
-rw-r--r--crypto/src/asn1/cms/KEKRecipientInfo.cs53
-rw-r--r--crypto/src/asn1/cms/KeyAgreeRecipientIdentifier.cs62
-rw-r--r--crypto/src/asn1/cms/KeyAgreeRecipientInfo.cs55
-rw-r--r--crypto/src/asn1/cms/KeyTransRecipientInfo.cs33
-rw-r--r--crypto/src/asn1/cms/MetaData.cs27
-rw-r--r--crypto/src/asn1/cms/OriginatorIdentifierOrKey.cs2
-rw-r--r--crypto/src/asn1/cms/OriginatorInfo.cs50
-rw-r--r--crypto/src/asn1/cms/OriginatorPublicKey.cs2
-rw-r--r--crypto/src/asn1/cms/OtherKeyAttribute.cs34
-rw-r--r--crypto/src/asn1/cms/OtherRecipientInfo.cs49
-rw-r--r--crypto/src/asn1/cms/OtherRevocationInfoFormat.cs43
-rw-r--r--crypto/src/asn1/cms/PasswordRecipientInfo.cs53
-rw-r--r--crypto/src/asn1/cms/RecipientEncryptedKey.cs62
-rw-r--r--crypto/src/asn1/cms/RecipientIdentifier.cs13
-rw-r--r--crypto/src/asn1/cms/RecipientInfo.cs39
-rw-r--r--crypto/src/asn1/cms/RecipientKeyIdentifier.cs50
-rw-r--r--crypto/src/asn1/cms/SCVPReqRes.cs25
-rw-r--r--crypto/src/asn1/cms/SignedData.cs23
-rw-r--r--crypto/src/asn1/cms/SignerIdentifier.cs50
-rw-r--r--crypto/src/asn1/cms/SignerInfo.cs28
-rw-r--r--crypto/src/asn1/cms/TimeStampAndCRL.cs31
-rw-r--r--crypto/src/asn1/cms/TimeStampTokenEvidence.cs38
-rw-r--r--crypto/src/asn1/cms/TimeStampedData.cs27
-rw-r--r--crypto/src/asn1/cms/ecc/MQVuserKeyingMaterial.cs56
-rw-r--r--crypto/src/cms/CMSUtils.cs2
-rw-r--r--crypto/src/cms/KeyTransRecipientInfoGenerator.cs2
-rw-r--r--crypto/src/cms/SignerInfoGenerator.cs3
-rw-r--r--crypto/src/crypto/operators/CmsKeyTransRecipientInfoGenerator.cs2
42 files changed, 530 insertions, 874 deletions
diff --git a/crypto/src/asn1/cms/Attribute.cs b/crypto/src/asn1/cms/Attribute.cs
index 69ac44148..d42aefccb 100644
--- a/crypto/src/asn1/cms/Attribute.cs
+++ b/crypto/src/asn1/cms/Attribute.cs
@@ -1,33 +1,25 @@
-using System;
-
-using Org.BouncyCastle.Utilities;
-
 namespace Org.BouncyCastle.Asn1.Cms
 {
     public class Attribute
         : Asn1Encodable
     {
-        private DerObjectIdentifier	attrType;
-        private 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 Attribute GetInstance(
-            object obj)
+        public static Attribute GetInstance(object obj)
         {
-            if (obj == null || obj is Attribute)
-				return (Attribute) obj;
-
-			if (obj is Asn1Sequence)
-                return new Attribute((Asn1Sequence) obj);
+            if (obj == null)
+                return null;
+            if (obj is Attribute attribute)
+                return attribute;
+            return new Attribute(Asn1Sequence.GetInstance(obj));
+        }
 
-            throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj");
+        public static Attribute GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new Attribute(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
         }
 
+        private DerObjectIdentifier	attrType;
+        private Asn1Set				attrValues;
+
 		public Attribute(
             Asn1Sequence seq)
         {
diff --git a/crypto/src/asn1/cms/Attributes.cs b/crypto/src/asn1/cms/Attributes.cs
index 010684158..6e3691870 100644
--- a/crypto/src/asn1/cms/Attributes.cs
+++ b/crypto/src/asn1/cms/Attributes.cs
@@ -1,5 +1,3 @@
-using System;
-
 namespace Org.BouncyCastle.Asn1.Cms
 {
     public class Attributes
@@ -16,7 +14,7 @@ namespace Org.BouncyCastle.Asn1.Cms
 
         public static Attributes GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
         {
-            return GetInstance(Asn1Set.GetInstance(taggedObject, declaredExplicit));
+            return new Attributes(Asn1Set.GetInstance(taggedObject, declaredExplicit));
         }
 
         private readonly Asn1Set m_attributes;
diff --git a/crypto/src/asn1/cms/AuthEnvelopedData.cs b/crypto/src/asn1/cms/AuthEnvelopedData.cs
index 8f980e6ec..bbcde8180 100644
--- a/crypto/src/asn1/cms/AuthEnvelopedData.cs
+++ b/crypto/src/asn1/cms/AuthEnvelopedData.cs
@@ -1,13 +1,25 @@
 using System;
 
-using Org.BouncyCastle.Utilities;
-
 namespace Org.BouncyCastle.Asn1.Cms
 {
-	public class AuthEnvelopedData
+    public class AuthEnvelopedData
 		: Asn1Encodable
 	{
-		private DerInteger				version;
+        public static AuthEnvelopedData GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is AuthEnvelopedData authEnvelopedData)
+                return authEnvelopedData;
+            return new AuthEnvelopedData(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static AuthEnvelopedData GetInstance(Asn1TaggedObject obj, bool isExplicit)
+        {
+            return new AuthEnvelopedData(Asn1Sequence.GetInstance(obj, isExplicit));
+        }
+
+        private DerInteger				version;
 		private OriginatorInfo			originatorInfo;
 		private Asn1Set					recipientInfos;
 		private EncryptedContentInfo	authEncryptedContentInfo;
@@ -100,41 +112,7 @@ namespace Org.BouncyCastle.Asn1.Cms
 			}
 		}
 
-		/**
-		 * return an AuthEnvelopedData object from a tagged object.
-		 *
-		 * @param obj      the tagged object holding the object we want.
-		 * @param isExplicit true if the object is meant to be explicitly
-		 *                 tagged false otherwise.
-		 * @throws ArgumentException if the object held by the
-		 *                                  tagged object cannot be converted.
-		 */
-		public static AuthEnvelopedData GetInstance(
-			Asn1TaggedObject	obj,
-			bool				isExplicit)
-		{
-			return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit));
-		}
-
-		/**
-		 * return an AuthEnvelopedData object from the given object.
-		 *
-		 * @param obj the object we want converted.
-		 * @throws ArgumentException if the object cannot be converted.
-		 */
-		public static AuthEnvelopedData GetInstance(
-			object	obj)
-		{
-			if (obj == null || obj is AuthEnvelopedData)
-				return (AuthEnvelopedData)obj;
-
-			if (obj is Asn1Sequence)
-				return new AuthEnvelopedData((Asn1Sequence)obj);
-
-            throw new ArgumentException("Invalid AuthEnvelopedData: " + Platform.GetTypeName(obj));
-		}
-
-		public DerInteger Version
+        public DerInteger Version
 		{
 			get { return version; }
 		}
diff --git a/crypto/src/asn1/cms/AuthenticatedData.cs b/crypto/src/asn1/cms/AuthenticatedData.cs
index 709617063..47db0fa16 100644
--- a/crypto/src/asn1/cms/AuthenticatedData.cs
+++ b/crypto/src/asn1/cms/AuthenticatedData.cs
@@ -1,14 +1,27 @@
 using System;
 
 using Org.BouncyCastle.Asn1.X509;
-using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Asn1.Cms
 {
-	public class AuthenticatedData
+    public class AuthenticatedData
 		: Asn1Encodable
 	{
-		private DerInteger version;
+        public static AuthenticatedData GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is AuthenticatedData authenticatedData)
+                return authenticatedData;
+            return new AuthenticatedData(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static AuthenticatedData GetInstance(Asn1TaggedObject obj, bool isExplicit)
+        {
+            return new AuthenticatedData(Asn1Sequence.GetInstance(obj, isExplicit));
+        }
+
+        private DerInteger version;
 		private OriginatorInfo originatorInfo;
 		private Asn1Set recipientInfos;
 		private AlgorithmIdentifier macAlgorithm;
@@ -88,45 +101,7 @@ namespace Org.BouncyCastle.Asn1.Cms
 			}
 		}
 
-		/**
-		 * return an AuthenticatedData object from a tagged object.
-		 *
-		 * @param obj      the tagged object holding the object we want.
-		 * @param isExplicit true if the object is meant to be explicitly
-		 *                 tagged false otherwise.
-		 * @throws ArgumentException if the object held by the
-		 *                                  tagged object cannot be converted.
-		 */
-		public static AuthenticatedData GetInstance(
-			Asn1TaggedObject	obj,
-			bool				isExplicit)
-		{
-			return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit));
-		}
-
-		/**
-		 * return an AuthenticatedData object from the given object.
-		 *
-		 * @param obj the object we want converted.
-		 * @throws ArgumentException if the object cannot be converted.
-		 */
-		public static AuthenticatedData GetInstance(
-			object	obj)
-		{
-			if (obj == null || obj is AuthenticatedData)
-			{
-				return (AuthenticatedData)obj;
-			}
-
-			if (obj is Asn1Sequence)
-			{
-				return new AuthenticatedData((Asn1Sequence)obj);
-			}
-
-            throw new ArgumentException("Invalid AuthenticatedData: " + Platform.GetTypeName(obj));
-		}
-
-		public DerInteger Version
+        public DerInteger Version
 		{
 			get { return version; }
 		}
diff --git a/crypto/src/asn1/cms/CcmParameters.cs b/crypto/src/asn1/cms/CcmParameters.cs
index c9588adca..bd725721b 100644
--- a/crypto/src/asn1/cms/CcmParameters.cs
+++ b/crypto/src/asn1/cms/CcmParameters.cs
@@ -9,9 +9,6 @@ namespace Org.BouncyCastle.Asn1.Cms
     {
         private const int DefaultIcvLen = 12;
 
-        private readonly byte[] m_nonce;
-        private readonly int m_icvLen;
-
         public static CcmParameters GetInstance(object obj)
         {
             if (obj == null)
@@ -23,9 +20,12 @@ namespace Org.BouncyCastle.Asn1.Cms
 
         public static CcmParameters GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
         {
-            return GetInstance(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+            return new CcmParameters(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
         }
 
+        private readonly byte[] m_nonce;
+        private readonly int m_icvLen;
+
         private CcmParameters(Asn1Sequence seq)
         {
             int count = seq.Count;
diff --git a/crypto/src/asn1/cms/CmsAlgorithmProtection.cs b/crypto/src/asn1/cms/CmsAlgorithmProtection.cs
index 9d21e53ff..cb7a23f84 100644
--- a/crypto/src/asn1/cms/CmsAlgorithmProtection.cs
+++ b/crypto/src/asn1/cms/CmsAlgorithmProtection.cs
@@ -23,6 +23,20 @@ namespace Org.BouncyCastle.Asn1.Cms
     public class CmsAlgorithmProtection
         : Asn1Encodable
     {
+        public static CmsAlgorithmProtection GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is CmsAlgorithmProtection cmsAlgorithmProtection)
+                return cmsAlgorithmProtection;
+            return new CmsAlgorithmProtection(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static CmsAlgorithmProtection GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new CmsAlgorithmProtection(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
+
         public static readonly int Signature = 1;
         public static readonly int Mac = 2;
 
@@ -78,15 +92,6 @@ namespace Org.BouncyCastle.Asn1.Cms
             }
         }
 
-        public static CmsAlgorithmProtection GetInstance(object obj)
-        {
-            if (obj == null)
-                return null;
-            if (obj is CmsAlgorithmProtection cmsAlgorithmProtection)
-                return cmsAlgorithmProtection;
-            return new CmsAlgorithmProtection(Asn1Sequence.GetInstance(obj));
-        }
-
         public AlgorithmIdentifier DigestAlgorithm => digestAlgorithm;
 
         public AlgorithmIdentifier MacAlgorithm => macAlgorithm;
diff --git a/crypto/src/asn1/cms/CompressedData.cs b/crypto/src/asn1/cms/CompressedData.cs
index 154ed35c0..e6ca41687 100644
--- a/crypto/src/asn1/cms/CompressedData.cs
+++ b/crypto/src/asn1/cms/CompressedData.cs
@@ -1,7 +1,4 @@
-using System;
-
 using Org.BouncyCastle.Asn1.X509;
-using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Asn1.Cms
 {
@@ -18,6 +15,20 @@ namespace Org.BouncyCastle.Asn1.Cms
     public class CompressedData
         : Asn1Encodable
     {
+        public static CompressedData GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is CompressedData compressedData)
+                return compressedData;
+            return new CompressedData(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static CompressedData GetInstance(Asn1TaggedObject ato, bool explicitly)
+        {
+            return new CompressedData(Asn1Sequence.GetInstance(ato, explicitly));
+        }
+
         private DerInteger			version;
         private AlgorithmIdentifier	compressionAlgorithm;
         private ContentInfo			encapContentInfo;
@@ -39,41 +50,7 @@ namespace Org.BouncyCastle.Asn1.Cms
             this.encapContentInfo = ContentInfo.GetInstance(seq[2]);
         }
 
-		/**
-         * return a CompressedData object from a tagged object.
-         *
-         * @param ato the tagged object holding the object we want.
-         * @param explicitly true if the object is meant to be explicitly
-         *              tagged false otherwise.
-         * @exception ArgumentException if the object held by the
-         *          tagged object cannot be converted.
-         */
-        public static CompressedData GetInstance(
-            Asn1TaggedObject ato,
-            bool explicitly)
-        {
-            return GetInstance(Asn1Sequence.GetInstance(ato, explicitly));
-        }
-
-        /**
-         * return a CompressedData object from the given object.
-         *
-         * @param _obj the object we want converted.
-         * @exception ArgumentException if the object cannot be converted.
-         */
-        public static CompressedData GetInstance(
-            object obj)
-        {
-            if (obj == null || obj is CompressedData)
-                return (CompressedData)obj;
-
-			if (obj is Asn1Sequence)
-                return new CompressedData((Asn1Sequence) obj);
-
-            throw new ArgumentException("Invalid CompressedData: " + Platform.GetTypeName(obj));
-        }
-
-		public DerInteger Version
+        public DerInteger Version
 		{
 			get { return version; }
 		}
diff --git a/crypto/src/asn1/cms/ContentInfo.cs b/crypto/src/asn1/cms/ContentInfo.cs
index c8f9fc65b..952884901 100644
--- a/crypto/src/asn1/cms/ContentInfo.cs
+++ b/crypto/src/asn1/cms/ContentInfo.cs
@@ -1,32 +1,27 @@
 using System;
 
-using Org.BouncyCastle.Utilities;
-
 namespace Org.BouncyCastle.Asn1.Cms
 {
     public class ContentInfo
         : Asn1Encodable
     {
-        private readonly DerObjectIdentifier	contentType;
-        private readonly Asn1Encodable			content;
-
-        public static ContentInfo GetInstance(
-            object obj)
+        public static ContentInfo GetInstance(object obj)
         {
-            if (obj == null || obj is ContentInfo)
-                return (ContentInfo) obj;
-
-            if (obj is Asn1Sequence)
-                return new ContentInfo((Asn1Sequence) obj);
-
-            throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj));
+            if (obj == null)
+                return null;
+            if (obj is ContentInfo contentInfo)
+                return contentInfo;
+            return new ContentInfo(Asn1Sequence.GetInstance(obj));
         }
 
         public static ContentInfo GetInstance(Asn1TaggedObject obj, bool isExplicit)
         {
-            return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit));
+            return new ContentInfo(Asn1Sequence.GetInstance(obj, isExplicit));
         }
 
+        private readonly DerObjectIdentifier	contentType;
+        private readonly Asn1Encodable			content;
+
         private ContentInfo(
             Asn1Sequence seq)
         {
diff --git a/crypto/src/asn1/cms/EncryptedContentInfo.cs b/crypto/src/asn1/cms/EncryptedContentInfo.cs
index 999f2a01e..2d4a744a3 100644
--- a/crypto/src/asn1/cms/EncryptedContentInfo.cs
+++ b/crypto/src/asn1/cms/EncryptedContentInfo.cs
@@ -1,13 +1,24 @@
-using System;
-
 using Org.BouncyCastle.Asn1.X509;
-using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Asn1.Cms
 {
     public class EncryptedContentInfo
         : Asn1Encodable
     {
+        public static EncryptedContentInfo GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is EncryptedContentInfo encryptedContentInfo)
+                return encryptedContentInfo;
+            return new EncryptedContentInfo(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static EncryptedContentInfo GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new EncryptedContentInfo(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
+
         private DerObjectIdentifier	contentType;
         private AlgorithmIdentifier	contentEncryptionAlgorithm;
         private Asn1OctetString		encryptedContent;
@@ -35,24 +46,6 @@ namespace Org.BouncyCastle.Asn1.Cms
             }
         }
 
-		/**
-         * return an EncryptedContentInfo object from the given object.
-         *
-         * @param obj the object we want converted.
-         * @exception ArgumentException if the object cannot be converted.
-         */
-        public static EncryptedContentInfo GetInstance(
-            object obj)
-        {
-            if (obj == null || obj is EncryptedContentInfo)
-                return (EncryptedContentInfo)obj;
-
-			if (obj is Asn1Sequence)
-                return new EncryptedContentInfo((Asn1Sequence)obj);
-
-            throw new ArgumentException("Invalid EncryptedContentInfo: " + Platform.GetTypeName(obj));
-        }
-
         public DerObjectIdentifier ContentType
         {
             get { return contentType; }
diff --git a/crypto/src/asn1/cms/EncryptedData.cs b/crypto/src/asn1/cms/EncryptedData.cs
index b8492d14b..a79f8119b 100644
--- a/crypto/src/asn1/cms/EncryptedData.cs
+++ b/crypto/src/asn1/cms/EncryptedData.cs
@@ -1,27 +1,27 @@
 using System;
 
-using Org.BouncyCastle.Utilities;
-
 namespace Org.BouncyCastle.Asn1.Cms
 {
-	public class EncryptedData
+    public class EncryptedData
 		: Asn1Encodable
 	{
-		private readonly DerInteger				version;
-		private readonly EncryptedContentInfo	encryptedContentInfo;
-		private readonly Asn1Set				unprotectedAttrs;
-
-		public static EncryptedData GetInstance(
-			object obj)
+        public static EncryptedData GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is EncryptedData encryptedData)
+                return encryptedData;
+            return new EncryptedData(Asn1Sequence.GetInstance(obj));
+        }
+
+		public static EncryptedData GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
 		{
-			if (obj is EncryptedData)
-				return (EncryptedData) obj;
+            return new EncryptedData(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
 
-			if (obj is Asn1Sequence)
-				return new EncryptedData((Asn1Sequence) obj);
-
-            throw new ArgumentException("Invalid EncryptedData: " + Platform.GetTypeName(obj));
-		}
+        private readonly DerInteger				version;
+		private readonly EncryptedContentInfo	encryptedContentInfo;
+		private readonly Asn1Set				unprotectedAttrs;
 
 		public EncryptedData(
 			EncryptedContentInfo encInfo)
diff --git a/crypto/src/asn1/cms/EnvelopedData.cs b/crypto/src/asn1/cms/EnvelopedData.cs
index 85216a2e8..1b88d7791 100644
--- a/crypto/src/asn1/cms/EnvelopedData.cs
+++ b/crypto/src/asn1/cms/EnvelopedData.cs
@@ -1,10 +1,22 @@
-using System;
-
 namespace Org.BouncyCastle.Asn1.Cms
 {
     public class EnvelopedData
         : Asn1Encodable
     {
+        public static EnvelopedData GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is EnvelopedData envelopedData)
+                return envelopedData;
+            return new EnvelopedData(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static EnvelopedData GetInstance(Asn1TaggedObject obj, bool explicitly)
+        {
+            return new EnvelopedData(Asn1Sequence.GetInstance(obj, explicitly));
+        }
+
         private DerInteger				version;
         private OriginatorInfo			originatorInfo;
         private Asn1Set					recipientInfos;
@@ -60,38 +72,6 @@ namespace Org.BouncyCastle.Asn1.Cms
             }
         }
 
-        /**
-         * return an EnvelopedData object from a tagged object.
-         *
-         * @param obj the tagged object holding the object we want.
-         * @param explicitly true if the object is meant to be explicitly
-         *              tagged false otherwise.
-         * @exception ArgumentException if the object held by the
-         *          tagged object cannot be converted.
-         */
-        public static EnvelopedData GetInstance(
-            Asn1TaggedObject	obj,
-            bool				explicitly)
-        {
-            return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
-        }
-
-        /**
-         * return an EnvelopedData object from the given object.
-         *
-         * @param obj the object we want converted.
-         * @exception ArgumentException if the object cannot be converted.
-         */
-        public static EnvelopedData GetInstance(
-            object obj)
-        {
-            if (obj is EnvelopedData)
-                return (EnvelopedData)obj;
-            if (obj == null)
-                return null;
-            return new EnvelopedData(Asn1Sequence.GetInstance(obj));
-        }
-
         public DerInteger Version
         {
             get { return version; }
diff --git a/crypto/src/asn1/cms/GcmParameters.cs b/crypto/src/asn1/cms/GcmParameters.cs
index bc86d27fa..06b4b88ca 100644
--- a/crypto/src/asn1/cms/GcmParameters.cs
+++ b/crypto/src/asn1/cms/GcmParameters.cs
@@ -9,9 +9,6 @@ namespace Org.BouncyCastle.Asn1.Cms
     {
         private const int DefaultIcvLen = 12;
 
-        private readonly byte[] m_nonce;
-        private readonly int m_icvLen;
-
         public static GcmParameters GetInstance(object obj)
         {
             if (obj == null)
@@ -23,9 +20,12 @@ namespace Org.BouncyCastle.Asn1.Cms
 
         public static GcmParameters GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
         {
-            return GetInstance(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+            return new GcmParameters(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
         }
 
+        private readonly byte[] m_nonce;
+        private readonly int m_icvLen;
+
         private GcmParameters(Asn1Sequence seq)
         {
             int count = seq.Count;
diff --git a/crypto/src/asn1/cms/IssuerAndSerialNumber.cs b/crypto/src/asn1/cms/IssuerAndSerialNumber.cs
index 8e31eb0e4..dcd489336 100644
--- a/crypto/src/asn1/cms/IssuerAndSerialNumber.cs
+++ b/crypto/src/asn1/cms/IssuerAndSerialNumber.cs
@@ -1,5 +1,3 @@
-using System;
-
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Math;
 
@@ -8,54 +6,51 @@ namespace Org.BouncyCastle.Asn1.Cms
     public class IssuerAndSerialNumber
         : Asn1Encodable
     {
-        private X509Name	name;
-        private DerInteger	serialNumber;
-
         public static IssuerAndSerialNumber GetInstance(object obj)
         {
             if (obj == null)
                 return null;
-            IssuerAndSerialNumber existing = obj as IssuerAndSerialNumber;
-            if (existing != null)
-                return existing;
+            if (obj is IssuerAndSerialNumber issuerAndSerialNumber)
+                return issuerAndSerialNumber;
             return new IssuerAndSerialNumber(Asn1Sequence.GetInstance(obj));
         }
 
-        private IssuerAndSerialNumber(Asn1Sequence seq)
+        public static IssuerAndSerialNumber GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
         {
-            this.name = X509Name.GetInstance(seq[0]);
-            this.serialNumber = (DerInteger) seq[1];
+            return new IssuerAndSerialNumber(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
         }
 
-        public IssuerAndSerialNumber(
-            X509Name	name,
-            BigInteger	serialNumber)
-        {
-            this.name = name;
-            this.serialNumber = new DerInteger(serialNumber);
-        }
+        private X509Name m_name;
+        private DerInteger m_serialNumber;
 
-        public IssuerAndSerialNumber(
-            X509Name	name,
-            DerInteger	serialNumber)
+        private IssuerAndSerialNumber(Asn1Sequence seq)
         {
-            this.name = name;
-            this.serialNumber = serialNumber;
+            m_name = X509Name.GetInstance(seq[0]);
+            m_serialNumber = DerInteger.GetInstance(seq[1]);
         }
 
-        public X509Name Name
+        public IssuerAndSerialNumber(X509Name name, BigInteger serialNumber)
         {
-            get { return name; }
+            m_name = name;
+            m_serialNumber = new DerInteger(serialNumber);
         }
 
-        public DerInteger SerialNumber
+        public IssuerAndSerialNumber(X509Name name, DerInteger serialNumber)
         {
-            get { return serialNumber; }
+            m_name = name;
+            m_serialNumber = serialNumber;
         }
 
-        public override Asn1Object ToAsn1Object()
+        public IssuerAndSerialNumber(X509CertificateStructure x509CertificateStructure)
         {
-            return new DerSequence(name, serialNumber);
+            m_name = x509CertificateStructure.Issuer;
+            m_serialNumber = x509CertificateStructure.SerialNumber;
         }
+
+        public X509Name Name => m_name;
+
+        public DerInteger SerialNumber => m_serialNumber;
+
+        public override Asn1Object ToAsn1Object() => new DerSequence(m_name, m_serialNumber);
     }
 }
diff --git a/crypto/src/asn1/cms/KEKIdentifier.cs b/crypto/src/asn1/cms/KEKIdentifier.cs
index 70ae8c438..09676fd0e 100644
--- a/crypto/src/asn1/cms/KEKIdentifier.cs
+++ b/crypto/src/asn1/cms/KEKIdentifier.cs
@@ -1,12 +1,24 @@
 using System;
 
-using Org.BouncyCastle.Utilities;
-
 namespace Org.BouncyCastle.Asn1.Cms
 {
     public class KekIdentifier
         : Asn1Encodable
     {
+        public static KekIdentifier GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is KekIdentifier kekIdentifier)
+                return kekIdentifier;
+            return new KekIdentifier(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static KekIdentifier GetInstance(Asn1TaggedObject obj, bool explicitly)
+        {
+            return new KekIdentifier(Asn1Sequence.GetInstance(obj, explicitly));
+        }
+
         private Asn1OctetString		keyIdentifier;
         private Asn1GeneralizedTime date;
         private OtherKeyAttribute	other;
@@ -48,41 +60,7 @@ namespace Org.BouncyCastle.Asn1.Cms
             }
         }
 
-		/**
-         * return a KekIdentifier object from a tagged object.
-         *
-         * @param obj the tagged object holding the object we want.
-         * @param explicitly true if the object is meant to be explicitly
-         *              tagged false otherwise.
-         * @exception ArgumentException if the object held by the
-         *          tagged object cannot be converted.
-         */
-        public static KekIdentifier GetInstance(
-            Asn1TaggedObject obj,
-            bool explicitly)
-        {
-            return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
-        }
-
-        /**
-         * return a KekIdentifier object from the given object.
-         *
-         * @param obj the object we want converted.
-         * @exception ArgumentException if the object cannot be converted.
-         */
-        public static KekIdentifier GetInstance(
-            object obj)
-        {
-            if (obj == null || obj is KekIdentifier)
-                return (KekIdentifier)obj;
-
-			if (obj is Asn1Sequence)
-                return new KekIdentifier((Asn1Sequence)obj);
-
-            throw new ArgumentException("Invalid KekIdentifier: " + Platform.GetTypeName(obj));
-        }
-
-		public Asn1OctetString KeyIdentifier
+        public Asn1OctetString KeyIdentifier
 		{
 			get { return keyIdentifier; }
 		}
diff --git a/crypto/src/asn1/cms/KEKRecipientInfo.cs b/crypto/src/asn1/cms/KEKRecipientInfo.cs
index 810e7fc97..6ab5f264f 100644
--- a/crypto/src/asn1/cms/KEKRecipientInfo.cs
+++ b/crypto/src/asn1/cms/KEKRecipientInfo.cs
@@ -1,13 +1,24 @@
-using System;
-
 using Org.BouncyCastle.Asn1.X509;
-using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Asn1.Cms
 {
     public class KekRecipientInfo
         : Asn1Encodable
     {
+        public static KekRecipientInfo GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is KekRecipientInfo kekRecipientInfo)
+                return kekRecipientInfo;
+            return new KekRecipientInfo(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static KekRecipientInfo GetInstance(Asn1TaggedObject obj, bool explicitly)
+        {
+            return new KekRecipientInfo(Asn1Sequence.GetInstance(obj, explicitly));
+        }
+
         private DerInteger			version;
         private KekIdentifier       kekID;
         private AlgorithmIdentifier keyEncryptionAlgorithm;
@@ -33,41 +44,7 @@ namespace Org.BouncyCastle.Asn1.Cms
             encryptedKey = (Asn1OctetString) seq[3];
         }
 
-		/**
-         * return a KekRecipientInfo object from a tagged object.
-         *
-         * @param obj the tagged object holding the object we want.
-         * @param explicitly true if the object is meant to be explicitly
-         *              tagged false otherwise.
-         * @exception ArgumentException if the object held by the
-         *          tagged object cannot be converted.
-         */
-        public static KekRecipientInfo GetInstance(
-            Asn1TaggedObject	obj,
-            bool				explicitly)
-        {
-            return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
-        }
-
-        /**
-         * return a KekRecipientInfo object from the given object.
-         *
-         * @param obj the object we want converted.
-         * @exception ArgumentException if the object cannot be converted.
-         */
-        public static KekRecipientInfo GetInstance(
-            object obj)
-        {
-            if (obj == null || obj is KekRecipientInfo)
-                return (KekRecipientInfo)obj;
-
-			if(obj is Asn1Sequence)
-                return new KekRecipientInfo((Asn1Sequence)obj);
-
-            throw new ArgumentException("Invalid KekRecipientInfo: " + Platform.GetTypeName(obj));
-        }
-
-		public DerInteger Version
+        public DerInteger Version
 		{
 			get { return version; }
 		}
diff --git a/crypto/src/asn1/cms/KeyAgreeRecipientIdentifier.cs b/crypto/src/asn1/cms/KeyAgreeRecipientIdentifier.cs
index 0256c2dc2..9e6e3bd5a 100644
--- a/crypto/src/asn1/cms/KeyAgreeRecipientIdentifier.cs
+++ b/crypto/src/asn1/cms/KeyAgreeRecipientIdentifier.cs
@@ -4,48 +4,36 @@ using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Asn1.Cms
 {
-	public class KeyAgreeRecipientIdentifier
+    public class KeyAgreeRecipientIdentifier
 		: Asn1Encodable, IAsn1Choice
 	{
-		/**
-		 * return an KeyAgreeRecipientIdentifier object from a tagged object.
-		 *
-		 * @param obj the tagged object holding the object we want.
-		 * @param isExplicit true if the object is meant to be explicitly
-		 *              tagged false otherwise.
-		 * @exception ArgumentException if the object held by the
-		 *          tagged object cannot be converted.
-		 */
-		public static KeyAgreeRecipientIdentifier GetInstance(
-			Asn1TaggedObject	obj,
-			bool				isExplicit)
-		{
-			return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit));
-		}
-    
-		/**
-		 * return an KeyAgreeRecipientIdentifier object from the given object.
-		 *
-		 * @param obj the object we want converted.
-		 * @exception ArgumentException if the object cannot be converted.
-		 */
-		public static KeyAgreeRecipientIdentifier GetInstance(
-			object obj)
-		{
-			if (obj == null || obj is KeyAgreeRecipientIdentifier)
-				return (KeyAgreeRecipientIdentifier)obj;
+        public static KeyAgreeRecipientIdentifier GetInstance(object obj)
+        {
+			if (obj == null)
+				return null;
 
-			if (obj is Asn1Sequence)
-				return new KeyAgreeRecipientIdentifier(IssuerAndSerialNumber.GetInstance(obj));
+			if (obj is KeyAgreeRecipientIdentifier keyAgreeRecipientIdentifier)
+				return keyAgreeRecipientIdentifier;
 
-			if (obj is Asn1TaggedObject && ((Asn1TaggedObject)obj).TagNo == 0)
-			{
-				return new KeyAgreeRecipientIdentifier(RecipientKeyIdentifier.GetInstance(
-					(Asn1TaggedObject)obj, false));
-			}
+			if (obj is IssuerAndSerialNumber issuerAndSerialNumber)
+				return new KeyAgreeRecipientIdentifier(issuerAndSerialNumber);
+
+            if (obj is Asn1Sequence sequence)
+                return new KeyAgreeRecipientIdentifier(IssuerAndSerialNumber.GetInstance(sequence));
+
+            if (obj is Asn1TaggedObject taggedObject)
+            {
+                if (taggedObject.HasContextTag(0))
+                    return new KeyAgreeRecipientIdentifier(RecipientKeyIdentifier.GetInstance(taggedObject, false));
+            }
 
-			throw new ArgumentException("Invalid KeyAgreeRecipientIdentifier: " + Platform.GetTypeName(obj), "obj");
-		} 
+			throw new ArgumentException("Invalid KeyAgreeRecipientIdentifier: " + Platform.GetTypeName(obj), nameof(obj));
+        }
+
+        public static KeyAgreeRecipientIdentifier GetInstance(Asn1TaggedObject obj, bool isExplicit)
+		{
+            return Asn1Utilities.GetInstanceFromChoice(obj, isExplicit, GetInstance);
+		}
 
 		private readonly IssuerAndSerialNumber issuerSerial;
 		private readonly RecipientKeyIdentifier rKeyID;
diff --git a/crypto/src/asn1/cms/KeyAgreeRecipientInfo.cs b/crypto/src/asn1/cms/KeyAgreeRecipientInfo.cs
index be2d76e2c..77f3f3748 100644
--- a/crypto/src/asn1/cms/KeyAgreeRecipientInfo.cs
+++ b/crypto/src/asn1/cms/KeyAgreeRecipientInfo.cs
@@ -1,13 +1,24 @@
-using System;
-
 using Org.BouncyCastle.Asn1.X509;
-using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Asn1.Cms
 {
     public class KeyAgreeRecipientInfo
         : Asn1Encodable
     {
+        public static KeyAgreeRecipientInfo GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is KeyAgreeRecipientInfo keyAgreeRecipientInfo)
+                return keyAgreeRecipientInfo;
+            return new KeyAgreeRecipientInfo(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static KeyAgreeRecipientInfo GetInstance(Asn1TaggedObject obj, bool explicitly)
+        {
+            return new KeyAgreeRecipientInfo(Asn1Sequence.GetInstance(obj, explicitly));
+        }
+
         private DerInteger                  version;
         private OriginatorIdentifierOrKey   originator;
         private Asn1OctetString             ukm;
@@ -45,43 +56,7 @@ namespace Org.BouncyCastle.Asn1.Cms
 			recipientEncryptedKeys = (Asn1Sequence)seq[index++];
         }
 
-		/**
-         * return a KeyAgreeRecipientInfo object from a tagged object.
-         *
-         * @param obj the tagged object holding the object we want.
-         * @param explicitly true if the object is meant to be explicitly
-         *              tagged false otherwise.
-         * @exception ArgumentException if the object held by the
-         *          tagged object cannot be converted.
-         */
-        public static KeyAgreeRecipientInfo GetInstance(
-            Asn1TaggedObject	obj,
-            bool				explicitly)
-        {
-            return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
-        }
-
-		/**
-         * return a KeyAgreeRecipientInfo object from the given object.
-         *
-         * @param obj the object we want converted.
-         * @exception ArgumentException if the object cannot be converted.
-         */
-        public static KeyAgreeRecipientInfo GetInstance(
-            object obj)
-        {
-            if (obj == null || obj is KeyAgreeRecipientInfo)
-                return (KeyAgreeRecipientInfo)obj;
-
-			if (obj is Asn1Sequence)
-                return new KeyAgreeRecipientInfo((Asn1Sequence)obj);
-
-			throw new ArgumentException(
-                "Illegal object in KeyAgreeRecipientInfo: " + Platform.GetTypeName(obj));
-
-        }
-
-		public DerInteger Version
+        public DerInteger Version
 		{
 			get { return version; }
 		}
diff --git a/crypto/src/asn1/cms/KeyTransRecipientInfo.cs b/crypto/src/asn1/cms/KeyTransRecipientInfo.cs
index 5e4fd22b4..c33ab8b73 100644
--- a/crypto/src/asn1/cms/KeyTransRecipientInfo.cs
+++ b/crypto/src/asn1/cms/KeyTransRecipientInfo.cs
@@ -8,6 +8,20 @@ namespace Org.BouncyCastle.Asn1.Cms
     public class KeyTransRecipientInfo
         : Asn1Encodable
     {
+        public static KeyTransRecipientInfo GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is KeyTransRecipientInfo keyTransRecipientInfo)
+                return keyTransRecipientInfo;
+            return new KeyTransRecipientInfo(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static KeyTransRecipientInfo GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new KeyTransRecipientInfo(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
+
         private DerInteger          version;
         private RecipientIdentifier rid;
         private AlgorithmIdentifier keyEncryptionAlgorithm;
@@ -41,25 +55,6 @@ namespace Org.BouncyCastle.Asn1.Cms
             this.encryptedKey = (Asn1OctetString) seq[3];
         }
 
-		/**
-         * return a KeyTransRecipientInfo object from the given object.
-         *
-         * @param obj the object we want converted.
-         * @exception ArgumentException if the object cannot be converted.
-         */
-        public static KeyTransRecipientInfo GetInstance(
-            object obj)
-        {
-            if (obj == null || obj is KeyTransRecipientInfo)
-                return (KeyTransRecipientInfo) obj;
-
-			if(obj is Asn1Sequence)
-                return new KeyTransRecipientInfo((Asn1Sequence) obj);
-
-			throw new ArgumentException(
-                "Illegal object in KeyTransRecipientInfo: " + Platform.GetTypeName(obj));
-        }
-
 		public DerInteger Version
 		{
 			get { return version; }
diff --git a/crypto/src/asn1/cms/MetaData.cs b/crypto/src/asn1/cms/MetaData.cs
index 6435d4d2e..a0d783d59 100644
--- a/crypto/src/asn1/cms/MetaData.cs
+++ b/crypto/src/asn1/cms/MetaData.cs
@@ -5,7 +5,21 @@ namespace Org.BouncyCastle.Asn1.Cms
 	public class MetaData
 		: Asn1Encodable
 	{
-		private DerBoolean hashProtected;
+        public static MetaData GetInstance(object obj)
+        {
+			if (obj == null)
+				return null;
+			if (obj is MetaData metaData)
+				return metaData;
+            return new MetaData(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static MetaData GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new MetaData(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
+
+        private DerBoolean hashProtected;
 		private DerUtf8String fileName;
 		private DerIA5String  mediaType;
 		private Attributes otherMetaData;
@@ -44,17 +58,6 @@ namespace Org.BouncyCastle.Asn1.Cms
 			}
 		}
 
-		public static MetaData GetInstance(object obj)
-		{
-			if (obj is MetaData)
-				return (MetaData)obj;
-
-			if (obj != null)
-				return new MetaData(Asn1Sequence.GetInstance(obj));
-
-			return null;
-		}
-
 		/**
 		 * <pre>
 		 * MetaData ::= SEQUENCE {
diff --git a/crypto/src/asn1/cms/OriginatorIdentifierOrKey.cs b/crypto/src/asn1/cms/OriginatorIdentifierOrKey.cs
index 69b860f5f..6d127ccc3 100644
--- a/crypto/src/asn1/cms/OriginatorIdentifierOrKey.cs
+++ b/crypto/src/asn1/cms/OriginatorIdentifierOrKey.cs
@@ -31,7 +31,7 @@ namespace Org.BouncyCastle.Asn1.Cms
                     return new OriginatorIdentifierOrKey(OriginatorPublicKey.GetInstance(taggedObject, false));
             }
 
-            throw new ArgumentException("Invalid OriginatorIdentifierOrKey: " + Platform.GetTypeName(o));
+            throw new ArgumentException("Invalid OriginatorIdentifierOrKey: " + Platform.GetTypeName(o), nameof(o));
         }
 
         public static OriginatorIdentifierOrKey GetInstance(Asn1TaggedObject o, bool explicitly)
diff --git a/crypto/src/asn1/cms/OriginatorInfo.cs b/crypto/src/asn1/cms/OriginatorInfo.cs
index c11e01dfe..e98fd0640 100644
--- a/crypto/src/asn1/cms/OriginatorInfo.cs
+++ b/crypto/src/asn1/cms/OriginatorInfo.cs
@@ -7,6 +7,20 @@ namespace Org.BouncyCastle.Asn1.Cms
     public class OriginatorInfo
         : Asn1Encodable
     {
+        public static OriginatorInfo GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is OriginatorInfo originatorInfo)
+                return originatorInfo;
+            return new OriginatorInfo(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static OriginatorInfo GetInstance(Asn1TaggedObject obj, bool explicitly)
+        {
+            return new OriginatorInfo(Asn1Sequence.GetInstance(obj, explicitly));
+        }
+
         private Asn1Set certs;
         private Asn1Set crls;
 
@@ -48,41 +62,7 @@ namespace Org.BouncyCastle.Asn1.Cms
             }
         }
 
-		/**
-         * return an OriginatorInfo object from a tagged object.
-         *
-         * @param obj the tagged object holding the object we want.
-         * @param explicitly true if the object is meant to be explicitly
-         *              tagged false otherwise.
-         * @exception ArgumentException if the object held by the
-         *          tagged object cannot be converted.
-         */
-        public static OriginatorInfo GetInstance(
-            Asn1TaggedObject	obj,
-            bool				explicitly)
-        {
-            return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
-        }
-
-		/**
-         * return an OriginatorInfo object from the given object.
-         *
-         * @param obj the object we want converted.
-         * @exception ArgumentException if the object cannot be converted.
-         */
-        public static OriginatorInfo GetInstance(
-            object obj)
-        {
-            if (obj == null || obj is OriginatorInfo)
-                return (OriginatorInfo)obj;
-
-			if (obj is Asn1Sequence)
-                return new OriginatorInfo((Asn1Sequence)obj);
-
-            throw new ArgumentException("Invalid OriginatorInfo: " + Platform.GetTypeName(obj));
-        }
-
-		public Asn1Set Certificates
+        public Asn1Set Certificates
 		{
 			get { return certs; }
 		}
diff --git a/crypto/src/asn1/cms/OriginatorPublicKey.cs b/crypto/src/asn1/cms/OriginatorPublicKey.cs
index 8c7c6b50f..6ed017877 100644
--- a/crypto/src/asn1/cms/OriginatorPublicKey.cs
+++ b/crypto/src/asn1/cms/OriginatorPublicKey.cs
@@ -16,7 +16,7 @@ namespace Org.BouncyCastle.Asn1.Cms
 
         public static OriginatorPublicKey GetInstance(Asn1TaggedObject obj, bool explicitly)
         {
-            return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
+            return new OriginatorPublicKey(Asn1Sequence.GetInstance(obj, explicitly));
         }
 
         private readonly AlgorithmIdentifier m_algorithm;
diff --git a/crypto/src/asn1/cms/OtherKeyAttribute.cs b/crypto/src/asn1/cms/OtherKeyAttribute.cs
index 285c88154..7c85de86e 100644
--- a/crypto/src/asn1/cms/OtherKeyAttribute.cs
+++ b/crypto/src/asn1/cms/OtherKeyAttribute.cs
@@ -1,33 +1,25 @@
-using System;
-
-using Org.BouncyCastle.Utilities;
-
 namespace Org.BouncyCastle.Asn1.Cms
 {
     public class OtherKeyAttribute
         : Asn1Encodable
     {
-        private DerObjectIdentifier	keyAttrId;
-        private Asn1Encodable		keyAttr;
-
-		/**
-         * return an OtherKeyAttribute object from the given object.
-         *
-         * @param o the object we want converted.
-         * @exception ArgumentException if the object cannot be converted.
-         */
-        public static OtherKeyAttribute GetInstance(
-            object obj)
+        public static OtherKeyAttribute GetInstance(object obj)
         {
-            if (obj == null || obj is OtherKeyAttribute)
-                return (OtherKeyAttribute) obj;
-
-			if (obj is Asn1Sequence)
-                return new OtherKeyAttribute((Asn1Sequence) obj);
+            if (obj == null)
+                return null;
+            if (obj is OtherKeyAttribute otherKeyAttribute)
+                return otherKeyAttribute;
+            return new OtherKeyAttribute(Asn1Sequence.GetInstance(obj));
+        }
 
-            throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(obj), "obj");
+        public static OtherKeyAttribute GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new OtherKeyAttribute(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
         }
 
+        private DerObjectIdentifier	keyAttrId;
+        private Asn1Encodable		keyAttr;
+
 		public OtherKeyAttribute(
             Asn1Sequence seq)
         {
diff --git a/crypto/src/asn1/cms/OtherRecipientInfo.cs b/crypto/src/asn1/cms/OtherRecipientInfo.cs
index eb5f6202e..989b6183e 100644
--- a/crypto/src/asn1/cms/OtherRecipientInfo.cs
+++ b/crypto/src/asn1/cms/OtherRecipientInfo.cs
@@ -1,10 +1,22 @@
-using System;
-
 namespace Org.BouncyCastle.Asn1.Cms
 {
     public class OtherRecipientInfo
         : Asn1Encodable
     {
+        public static OtherRecipientInfo GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is OtherRecipientInfo otherRecipientInfo)
+                return otherRecipientInfo;
+            return new OtherRecipientInfo(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static OtherRecipientInfo GetInstance(Asn1TaggedObject obj, bool explicitly)
+        {
+            return new OtherRecipientInfo(Asn1Sequence.GetInstance(obj, explicitly));
+        }
+
         private readonly DerObjectIdentifier oriType;
         private readonly Asn1Encodable oriValue;
 
@@ -22,39 +34,6 @@ namespace Org.BouncyCastle.Asn1.Cms
             oriValue = seq[1];
         }
 
-        /**
-         * return a OtherRecipientInfo object from a tagged object.
-         *
-         * @param obj the tagged object holding the object we want.
-         * @param explicitly true if the object is meant to be explicitly
-         *              tagged false otherwise.
-         * @exception ArgumentException if the object held by the
-         *          tagged object cannot be converted.
-         */
-        public static OtherRecipientInfo GetInstance(
-            Asn1TaggedObject	obj,
-            bool				explicitly)
-        {
-            return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
-        }
-
-        /**
-         * return a OtherRecipientInfo object from the given object.
-         *
-         * @param obj the object we want converted.
-         * @exception ArgumentException if the object cannot be converted.
-         */
-        public static OtherRecipientInfo GetInstance(
-            object obj)
-        {
-            if (obj == null)
-                return null;
-            OtherRecipientInfo existing = obj as OtherRecipientInfo;
-            if (existing != null)
-                return existing;
-            return new OtherRecipientInfo(Asn1Sequence.GetInstance(obj));
-        }
-
         public virtual DerObjectIdentifier OriType
         {
             get { return oriType; }
diff --git a/crypto/src/asn1/cms/OtherRevocationInfoFormat.cs b/crypto/src/asn1/cms/OtherRevocationInfoFormat.cs
index f6335cdac..d39f14aa8 100644
--- a/crypto/src/asn1/cms/OtherRevocationInfoFormat.cs
+++ b/crypto/src/asn1/cms/OtherRevocationInfoFormat.cs
@@ -3,6 +3,20 @@
     public class OtherRevocationInfoFormat
         : Asn1Encodable
     {
+        public static OtherRevocationInfoFormat GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is OtherRevocationInfoFormat otherRevocationInfoFormat)
+                return otherRevocationInfoFormat;
+            return new OtherRevocationInfoFormat(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static OtherRevocationInfoFormat GetInstance(Asn1TaggedObject obj, bool isExplicit)
+        {
+            return new OtherRevocationInfoFormat(Asn1Sequence.GetInstance(obj, isExplicit));
+        }
+
         private readonly DerObjectIdentifier otherRevInfoFormat;
         private readonly Asn1Encodable otherRevInfo;
 
@@ -20,35 +34,6 @@
             otherRevInfo = seq[1];
         }
 
-        /**
-         * return a OtherRevocationInfoFormat object from a tagged object.
-         *
-         * @param obj the tagged object holding the object we want.
-         * @param explicit true if the object is meant to be explicitly
-         *              tagged false otherwise.
-         * @exception IllegalArgumentException if the object held by the
-         *          tagged object cannot be converted.
-         */
-        public static OtherRevocationInfoFormat GetInstance(Asn1TaggedObject obj, bool isExplicit)
-        {
-            return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit));
-        }
-
-        /**
-         * return a OtherRevocationInfoFormat object from the given object.
-         *
-         * @param obj the object we want converted.
-         * @exception IllegalArgumentException if the object cannot be converted.
-         */
-        public static OtherRevocationInfoFormat GetInstance(object obj)
-        {
-            if (obj is OtherRevocationInfoFormat otherRevocationInfoFormat)
-                return otherRevocationInfoFormat;
-            if (obj != null)
-                return new OtherRevocationInfoFormat(Asn1Sequence.GetInstance(obj));
-            return null;
-        }
-
         public virtual DerObjectIdentifier InfoFormat
         {
             get { return otherRevInfoFormat; }
diff --git a/crypto/src/asn1/cms/PasswordRecipientInfo.cs b/crypto/src/asn1/cms/PasswordRecipientInfo.cs
index 9fb639bf3..c25d61a46 100644
--- a/crypto/src/asn1/cms/PasswordRecipientInfo.cs
+++ b/crypto/src/asn1/cms/PasswordRecipientInfo.cs
@@ -1,13 +1,24 @@
-using System;
-
 using Org.BouncyCastle.Asn1.X509;
-using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Asn1.Cms
 {
     public class PasswordRecipientInfo
         : Asn1Encodable
     {
+        public static PasswordRecipientInfo GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is PasswordRecipientInfo passwordRecipientInfo)
+                return passwordRecipientInfo;
+            return new PasswordRecipientInfo(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static PasswordRecipientInfo GetInstance(Asn1TaggedObject obj, bool explicitly)
+        {
+            return new PasswordRecipientInfo(Asn1Sequence.GetInstance(obj, explicitly));
+        }
+
         private readonly DerInteger				version;
         private readonly AlgorithmIdentifier	keyDerivationAlgorithm;
         private readonly AlgorithmIdentifier	keyEncryptionAlgorithm;
@@ -50,41 +61,7 @@ namespace Org.BouncyCastle.Asn1.Cms
             }
         }
 
-		/**
-         * return a PasswordRecipientInfo object from a tagged object.
-         *
-         * @param obj the tagged object holding the object we want.
-         * @param explicitly true if the object is meant to be explicitly
-         *              tagged false otherwise.
-         * @exception ArgumentException if the object held by the
-         *          tagged object cannot be converted.
-         */
-        public static PasswordRecipientInfo GetInstance(
-            Asn1TaggedObject	obj,
-            bool				explicitly)
-        {
-            return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
-        }
-
-		/**
-         * return a PasswordRecipientInfo object from the given object.
-         *
-         * @param obj the object we want converted.
-         * @exception ArgumentException if the object cannot be converted.
-         */
-        public static PasswordRecipientInfo GetInstance(
-            object obj)
-        {
-            if (obj == null || obj is PasswordRecipientInfo)
-                return (PasswordRecipientInfo) obj;
-
-			if (obj is Asn1Sequence)
-                return new PasswordRecipientInfo((Asn1Sequence) obj);
-
-            throw new ArgumentException("Invalid PasswordRecipientInfo: " + Platform.GetTypeName(obj));
-        }
-
-		public DerInteger Version
+        public DerInteger Version
 		{
 			get { return version; }
 		}
diff --git a/crypto/src/asn1/cms/RecipientEncryptedKey.cs b/crypto/src/asn1/cms/RecipientEncryptedKey.cs
index 1afba4ab1..0e0214909 100644
--- a/crypto/src/asn1/cms/RecipientEncryptedKey.cs
+++ b/crypto/src/asn1/cms/RecipientEncryptedKey.cs
@@ -1,13 +1,23 @@
-using System;
-
-using Org.BouncyCastle.Utilities;
-
 namespace Org.BouncyCastle.Asn1.Cms
 {
-	public class RecipientEncryptedKey
+    public class RecipientEncryptedKey
 		: Asn1Encodable
 	{
-		private readonly KeyAgreeRecipientIdentifier identifier;
+        public static RecipientEncryptedKey GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is RecipientEncryptedKey recipientEncryptedKey)
+                return recipientEncryptedKey;
+            return new RecipientEncryptedKey(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static RecipientEncryptedKey GetInstance(Asn1TaggedObject obj, bool isExplicit)
+        {
+            return new RecipientEncryptedKey(Asn1Sequence.GetInstance(obj, isExplicit));
+        }
+
+        private readonly KeyAgreeRecipientIdentifier identifier;
 		private readonly Asn1OctetString encryptedKey;
 
 		private RecipientEncryptedKey(
@@ -17,45 +27,7 @@ namespace Org.BouncyCastle.Asn1.Cms
 			encryptedKey = (Asn1OctetString) seq[1];
 		}
 
-		/**
-		 * return an RecipientEncryptedKey object from a tagged object.
-		 *
-		 * @param obj the tagged object holding the object we want.
-		 * @param isExplicit true if the object is meant to be explicitly
-		 *              tagged false otherwise.
-		 * @exception ArgumentException if the object held by the
-		 *          tagged object cannot be converted.
-		 */
-		public static RecipientEncryptedKey GetInstance(
-			Asn1TaggedObject	obj,
-			bool				isExplicit)
-		{
-			return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit));
-		}
-
-		/**
-		 * return a RecipientEncryptedKey object from the given object.
-		 *
-		 * @param obj the object we want converted.
-		 * @exception ArgumentException if the object cannot be converted.
-		 */
-		public static RecipientEncryptedKey GetInstance(
-			object obj)
-		{
-			if (obj == null || obj is RecipientEncryptedKey)
-			{
-				return (RecipientEncryptedKey) obj;
-			}
-
-			if (obj is Asn1Sequence)
-			{
-				return new RecipientEncryptedKey((Asn1Sequence) obj);
-			}
-
-			throw new ArgumentException("Invalid RecipientEncryptedKey: " + Platform.GetTypeName(obj), "obj");
-		}
-
-		public RecipientEncryptedKey(
+        public RecipientEncryptedKey(
 			KeyAgreeRecipientIdentifier	id,
 			Asn1OctetString				encryptedKey)
 		{
diff --git a/crypto/src/asn1/cms/RecipientIdentifier.cs b/crypto/src/asn1/cms/RecipientIdentifier.cs
index 22ac76340..de9fd5e75 100644
--- a/crypto/src/asn1/cms/RecipientIdentifier.cs
+++ b/crypto/src/asn1/cms/RecipientIdentifier.cs
@@ -7,12 +7,6 @@ namespace Org.BouncyCastle.Asn1.Cms
     public class RecipientIdentifier
         : Asn1Encodable, IAsn1Choice
     {
-        /**
-         * return a RecipientIdentifier object from the given object.
-         *
-         * @param o the object we want converted.
-         * @exception ArgumentException if the object cannot be converted.
-         */
         public static RecipientIdentifier GetInstance(object o)
         {
             if (o == null)
@@ -26,7 +20,12 @@ namespace Org.BouncyCastle.Asn1.Cms
             if (o is Asn1Object asn1Object)
                 return new RecipientIdentifier(asn1Object);
 
-            throw new ArgumentException("Illegal object in RecipientIdentifier: " + Platform.GetTypeName(o));
+            throw new ArgumentException("Illegal object in RecipientIdentifier: " + Platform.GetTypeName(o), nameof(o));
+        }
+
+        public static RecipientIdentifier GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return Asn1Utilities.GetInstanceFromChoice(taggedObject, declaredExplicit, GetInstance);
         }
 
         private readonly Asn1Encodable m_id;
diff --git a/crypto/src/asn1/cms/RecipientInfo.cs b/crypto/src/asn1/cms/RecipientInfo.cs
index 3f5ccea5b..ff93258b6 100644
--- a/crypto/src/asn1/cms/RecipientInfo.cs
+++ b/crypto/src/asn1/cms/RecipientInfo.cs
@@ -7,6 +7,28 @@ namespace Org.BouncyCastle.Asn1.Cms
     public class RecipientInfo
         : Asn1Encodable, IAsn1Choice
     {
+        public static RecipientInfo GetInstance(object o)
+        {
+            if (o == null)
+                return null;
+
+            if (o is RecipientInfo recipientInfo)
+                return recipientInfo;
+
+            if (o is Asn1Sequence sequence)
+                return new RecipientInfo(sequence);
+
+            if (o is Asn1TaggedObject taggedObject)
+                return new RecipientInfo(taggedObject);
+
+            throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(o), nameof(o));
+        }
+
+        public static RecipientInfo GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return Asn1Utilities.GetInstanceFromChoice(taggedObject, declaredExplicit, GetInstance);
+        }
+
         internal Asn1Encodable info;
 
 		public RecipientInfo(
@@ -45,23 +67,6 @@ namespace Org.BouncyCastle.Asn1.Cms
             this.info = info;
         }
 
-		public static RecipientInfo GetInstance(object o)
-        {
-			if (o == null)
-				return null;
-
-            if (o is RecipientInfo recipientInfo)
-                return recipientInfo;
-
-			if (o is Asn1Sequence sequence)
-                return new RecipientInfo(sequence);
-
-			if (o is Asn1TaggedObject taggedObject)
-                return new RecipientInfo(taggedObject);
-
-            throw new ArgumentException("unknown object in factory: " + Platform.GetTypeName(o));
-        }
-
 		public DerInteger Version
         {
 			get
diff --git a/crypto/src/asn1/cms/RecipientKeyIdentifier.cs b/crypto/src/asn1/cms/RecipientKeyIdentifier.cs
index 60a6151bf..9a340b24f 100644
--- a/crypto/src/asn1/cms/RecipientKeyIdentifier.cs
+++ b/crypto/src/asn1/cms/RecipientKeyIdentifier.cs
@@ -7,6 +7,20 @@ namespace Org.BouncyCastle.Asn1.Cms
     public class RecipientKeyIdentifier
         : Asn1Encodable
     {
+        public static RecipientKeyIdentifier GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is RecipientKeyIdentifier recipientKeyIdentifier)
+                return recipientKeyIdentifier;
+            return new RecipientKeyIdentifier(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static RecipientKeyIdentifier GetInstance(Asn1TaggedObject ato, bool explicitly)
+        {
+            return new RecipientKeyIdentifier(Asn1Sequence.GetInstance(ato, explicitly));
+        }
+
         private Asn1OctetString      subjectKeyIdentifier;
         private Asn1GeneralizedTime  date;
         private OtherKeyAttribute    other;
@@ -64,41 +78,7 @@ namespace Org.BouncyCastle.Asn1.Cms
             }
         }
 
-		/**
-         * return a RecipientKeyIdentifier object from a tagged object.
-         *
-         * @param _ato the tagged object holding the object we want.
-         * @param _explicit true if the object is meant to be explicitly
-         *              tagged false otherwise.
-         * @exception ArgumentException if the object held by the
-         *          tagged object cannot be converted.
-         */
-        public static RecipientKeyIdentifier GetInstance(
-			Asn1TaggedObject	ato,
-			bool				explicitly)
-		{
-            return GetInstance(Asn1Sequence.GetInstance(ato, explicitly));
-        }
-
-		/**
-         * return a RecipientKeyIdentifier object from the given object.
-         *
-         * @param _obj the object we want converted.
-         * @exception ArgumentException if the object cannot be converted.
-         */
-        public static RecipientKeyIdentifier GetInstance(
-			object obj)
-		{
-            if (obj == null || obj is RecipientKeyIdentifier)
-                return (RecipientKeyIdentifier) obj;
-
-			if (obj is Asn1Sequence)
-				return new RecipientKeyIdentifier((Asn1Sequence) obj);
-
-            throw new ArgumentException("Invalid RecipientKeyIdentifier: " + Platform.GetTypeName(obj));
-        }
-
-		public Asn1OctetString SubjectKeyIdentifier
+        public Asn1OctetString SubjectKeyIdentifier
 		{
 			get { return subjectKeyIdentifier; }
 		}
diff --git a/crypto/src/asn1/cms/SCVPReqRes.cs b/crypto/src/asn1/cms/SCVPReqRes.cs
index 8b5f858a6..ec36ff9fa 100644
--- a/crypto/src/asn1/cms/SCVPReqRes.cs
+++ b/crypto/src/asn1/cms/SCVPReqRes.cs
@@ -1,22 +1,25 @@
-using System;
-
-namespace Org.BouncyCastle.Asn1.Cms
+namespace Org.BouncyCastle.Asn1.Cms
 {
     public class ScvpReqRes
         : Asn1Encodable
     {
-        private readonly ContentInfo request;
-        private readonly ContentInfo response;
+        public static ScvpReqRes GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is ScvpReqRes scvpReqRes)
+                return scvpReqRes;
+            return new ScvpReqRes(Asn1Sequence.GetInstance(obj));
+        }
 
-        public static ScvpReqRes GetInstance(object  obj)
+        public static ScvpReqRes GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
         {
-            if (obj is ScvpReqRes)
-                return (ScvpReqRes)obj;
-            if (obj != null)
-                return new ScvpReqRes(Asn1Sequence.GetInstance(obj));
-            return null;
+            return new ScvpReqRes(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
         }
 
+        private readonly ContentInfo request;
+        private readonly ContentInfo response;
+
         private ScvpReqRes(Asn1Sequence seq)
         {
             if (seq[0] is Asn1TaggedObject taggedObject)
diff --git a/crypto/src/asn1/cms/SignedData.cs b/crypto/src/asn1/cms/SignedData.cs
index 9018bc6fd..858715ad6 100644
--- a/crypto/src/asn1/cms/SignedData.cs
+++ b/crypto/src/asn1/cms/SignedData.cs
@@ -8,6 +8,20 @@ namespace Org.BouncyCastle.Asn1.Cms
     public class SignedData
         : Asn1Encodable
     {
+        public static SignedData GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is SignedData signedData)
+                return signedData;
+            return new SignedData(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static SignedData GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new SignedData(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
+
         private static readonly DerInteger Version1 = new DerInteger(1);
         private static readonly DerInteger Version3 = new DerInteger(3);
         private static readonly DerInteger Version4 = new DerInteger(4);
@@ -22,15 +36,6 @@ namespace Org.BouncyCastle.Asn1.Cms
         private readonly bool			certsBer;
         private readonly bool		    crlsBer;
 
-        public static SignedData GetInstance(object obj)
-        {
-            if (obj is SignedData signedData)
-                return signedData;
-            if (obj == null)
-                return null;
-            return new SignedData(Asn1Sequence.GetInstance(obj));
-        }
-
         public SignedData(
             Asn1Set     digestAlgorithms,
             ContentInfo contentInfo,
diff --git a/crypto/src/asn1/cms/SignerIdentifier.cs b/crypto/src/asn1/cms/SignerIdentifier.cs
index 9edf6a8c8..17f3f08c2 100644
--- a/crypto/src/asn1/cms/SignerIdentifier.cs
+++ b/crypto/src/asn1/cms/SignerIdentifier.cs
@@ -7,6 +7,31 @@ namespace Org.BouncyCastle.Asn1.Cms
     public class SignerIdentifier
         : Asn1Encodable, IAsn1Choice
     {
+        public static SignerIdentifier GetInstance(object o)
+        {
+            if (o == null)
+                return null;
+
+            if (o is SignerIdentifier signerIdentifier)
+                return signerIdentifier;
+
+            if (o is IssuerAndSerialNumber issuerAndSerialNumber)
+                return new SignerIdentifier(issuerAndSerialNumber);
+
+            if (o is Asn1OctetString octetString)
+                return new SignerIdentifier(octetString);
+
+            if (o is Asn1Object asn1Object)
+                return new SignerIdentifier(asn1Object);
+
+            throw new ArgumentException("Illegal object in SignerIdentifier: " + Platform.GetTypeName(o), nameof(o));
+        }
+
+        public static SignerIdentifier GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return Asn1Utilities.GetInstanceFromChoice(taggedObject, declaredExplicit, GetInstance);
+        }
+
         private Asn1Encodable id;
 
 		public SignerIdentifier(
@@ -27,31 +52,6 @@ namespace Org.BouncyCastle.Asn1.Cms
             this.id = id;
         }
 
-		/**
-         * return a SignerIdentifier object from the given object.
-         *
-         * @param o the object we want converted.
-         * @exception ArgumentException if the object cannot be converted.
-         */
-        public static SignerIdentifier GetInstance(
-            object o)
-        {
-            if (o == null || o is SignerIdentifier)
-                return (SignerIdentifier) o;
-
-			if (o is IssuerAndSerialNumber)
-                return new SignerIdentifier((IssuerAndSerialNumber) o);
-
-			if (o is Asn1OctetString)
-                return new SignerIdentifier((Asn1OctetString) o);
-
-			if (o is Asn1Object)
-                return new SignerIdentifier((Asn1Object) o);
-
-			throw new ArgumentException(
-                "Illegal object in SignerIdentifier: " + Platform.GetTypeName(o));
-        }
-
 		public bool IsTagged
 		{
 			get { return (id is Asn1TaggedObject); }
diff --git a/crypto/src/asn1/cms/SignerInfo.cs b/crypto/src/asn1/cms/SignerInfo.cs
index dbd0125c4..bce33e699 100644
--- a/crypto/src/asn1/cms/SignerInfo.cs
+++ b/crypto/src/asn1/cms/SignerInfo.cs
@@ -1,13 +1,24 @@
-using System;
-
 using Org.BouncyCastle.Asn1.X509;
-using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Asn1.Cms
 {
     public class SignerInfo
         : Asn1Encodable
     {
+        public static SignerInfo GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is SignerInfo signerInfo)
+                return signerInfo;
+            return new SignerInfo(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static SignerInfo GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new SignerInfo(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
+
         private DerInteger              version;
         private SignerIdentifier        sid;
         private AlgorithmIdentifier     digAlgorithm;
@@ -16,17 +27,6 @@ namespace Org.BouncyCastle.Asn1.Cms
         private Asn1OctetString         encryptedDigest;
         private Asn1Set                 unauthenticatedAttributes;
 
-        public static SignerInfo GetInstance(object obj)
-        {
-            if (obj == null || obj is SignerInfo)
-                return (SignerInfo) obj;
-
-            if (obj is Asn1Sequence)
-                return new SignerInfo((Asn1Sequence) obj);
-
-            throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj");
-        }
-
         public SignerInfo(
             SignerIdentifier        sid,
             AlgorithmIdentifier     digAlgorithm,
diff --git a/crypto/src/asn1/cms/TimeStampAndCRL.cs b/crypto/src/asn1/cms/TimeStampAndCRL.cs
index 4cb5f2a52..c0cd48905 100644
--- a/crypto/src/asn1/cms/TimeStampAndCRL.cs
+++ b/crypto/src/asn1/cms/TimeStampAndCRL.cs
@@ -1,11 +1,23 @@
-using System;
-
 namespace Org.BouncyCastle.Asn1.Cms
 {
-	public class TimeStampAndCrl
+    public class TimeStampAndCrl
 		: Asn1Encodable
 	{
-		private ContentInfo timeStamp;
+        public static TimeStampAndCrl GetInstance(object obj)
+        {
+			if (obj == null)
+				return null;
+            if (obj is TimeStampAndCrl timeStampAndCrl)
+                return timeStampAndCrl;
+            return new TimeStampAndCrl(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static TimeStampAndCrl GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new TimeStampAndCrl(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
+
+        private ContentInfo timeStamp;
 		private X509.CertificateList crl;
 
 		public TimeStampAndCrl(ContentInfo timeStamp)
@@ -22,17 +34,6 @@ namespace Org.BouncyCastle.Asn1.Cms
 			}
 		}
 
-		public static TimeStampAndCrl GetInstance(object obj)
-		{
-			if (obj is TimeStampAndCrl)
-				return (TimeStampAndCrl)obj;
-
-			if (obj != null)
-				return new TimeStampAndCrl(Asn1Sequence.GetInstance(obj));
-
-			return null;
-		}
-
 		public virtual ContentInfo TimeStampToken
 		{
 			get { return this.timeStamp; }
diff --git a/crypto/src/asn1/cms/TimeStampTokenEvidence.cs b/crypto/src/asn1/cms/TimeStampTokenEvidence.cs
index 8625d058e..6ac1eb11d 100644
--- a/crypto/src/asn1/cms/TimeStampTokenEvidence.cs
+++ b/crypto/src/asn1/cms/TimeStampTokenEvidence.cs
@@ -1,11 +1,23 @@
-using System;
-
 namespace Org.BouncyCastle.Asn1.Cms
 {
-	public class TimeStampTokenEvidence
+    public class TimeStampTokenEvidence
 		: Asn1Encodable
 	{
-		private TimeStampAndCrl[] timeStampAndCrls;
+        public static TimeStampTokenEvidence GetInstance(object obj)
+        {
+			if (obj == null)
+				return null;
+			if (obj is TimeStampTokenEvidence timeStampTokenEvidence)
+				return timeStampTokenEvidence;
+            return new TimeStampTokenEvidence(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static TimeStampTokenEvidence GetInstance(Asn1TaggedObject tagged, bool isExplicit)
+        {
+            return new TimeStampTokenEvidence(Asn1Sequence.GetInstance(tagged, isExplicit));
+        }
+
+        private TimeStampAndCrl[] timeStampAndCrls;
 
 		public TimeStampTokenEvidence(TimeStampAndCrl[] timeStampAndCrls)
 		{
@@ -29,23 +41,7 @@ namespace Org.BouncyCastle.Asn1.Cms
 			}
 		}
 
-		public static TimeStampTokenEvidence GetInstance(Asn1TaggedObject tagged, bool isExplicit)
-		{
-			return GetInstance(Asn1Sequence.GetInstance(tagged, isExplicit));
-		}
-
-		public static TimeStampTokenEvidence GetInstance(object obj)
-		{
-			if (obj is TimeStampTokenEvidence)
-				return (TimeStampTokenEvidence)obj;
-
-			if (obj != null)
-				return new TimeStampTokenEvidence(Asn1Sequence.GetInstance(obj));
-
-			return null;
-		}
-
-		public virtual TimeStampAndCrl[] ToTimeStampAndCrlArray()
+        public virtual TimeStampAndCrl[] ToTimeStampAndCrlArray()
 		{
 			return (TimeStampAndCrl[])timeStampAndCrls.Clone();
 		}
diff --git a/crypto/src/asn1/cms/TimeStampedData.cs b/crypto/src/asn1/cms/TimeStampedData.cs
index f90e5b086..4d9136ea0 100644
--- a/crypto/src/asn1/cms/TimeStampedData.cs
+++ b/crypto/src/asn1/cms/TimeStampedData.cs
@@ -5,7 +5,21 @@ namespace Org.BouncyCastle.Asn1.Cms
 	public class TimeStampedData
 		: Asn1Encodable
 	{
-		private DerInteger version;
+        public static TimeStampedData GetInstance(object obj)
+        {
+			if (obj == null)
+				return null;
+			if (obj is TimeStampedData timeStampedData)
+				return timeStampedData;
+            return new TimeStampedData(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static TimeStampedData GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new TimeStampedData(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
+
+        private DerInteger version;
 		private DerIA5String dataUri;
 		private MetaData metaData;
 		private Asn1OctetString content;
@@ -43,17 +57,6 @@ namespace Org.BouncyCastle.Asn1.Cms
 			this.temporalEvidence = Evidence.GetInstance(seq[index]);
 		}
 
-		public static TimeStampedData GetInstance(object obj)
-		{
-			if (obj is TimeStampedData)
-				return (TimeStampedData)obj;
-
-			if (obj != null)
-				return new TimeStampedData(Asn1Sequence.GetInstance(obj));
-
-			return null;
-		}
-
 		public virtual DerIA5String DataUri
 		{
 			get { return dataUri; }
diff --git a/crypto/src/asn1/cms/ecc/MQVuserKeyingMaterial.cs b/crypto/src/asn1/cms/ecc/MQVuserKeyingMaterial.cs
index 3a4761e78..047017351 100644
--- a/crypto/src/asn1/cms/ecc/MQVuserKeyingMaterial.cs
+++ b/crypto/src/asn1/cms/ecc/MQVuserKeyingMaterial.cs
@@ -7,7 +7,21 @@ namespace Org.BouncyCastle.Asn1.Cms.Ecc
 	public class MQVuserKeyingMaterial
 		: Asn1Encodable
 	{
-		private OriginatorPublicKey	ephemeralPublicKey;
+        public static MQVuserKeyingMaterial GetInstance(object obj)
+        {
+			if (obj == null)
+				return null;
+			if (obj is MQVuserKeyingMaterial mqvUserKeyingMaterial)
+				return mqvUserKeyingMaterial;
+            return new MQVuserKeyingMaterial(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static MQVuserKeyingMaterial GetInstance(Asn1TaggedObject obj, bool isExplicit)
+        {
+            return new MQVuserKeyingMaterial(Asn1Sequence.GetInstance(obj, isExplicit));
+        }
+
+        private OriginatorPublicKey	ephemeralPublicKey;
 		private Asn1OctetString		addedukm;
 
 		public MQVuserKeyingMaterial(
@@ -34,45 +48,7 @@ namespace Org.BouncyCastle.Asn1.Cms.Ecc
 			}
 		}
 
-		/**
-		 * return an AuthEnvelopedData object from a tagged object.
-		 *
-		 * @param obj      the tagged object holding the object we want.
-		 * @param isExplicit true if the object is meant to be explicitly
-		 *                 tagged false otherwise.
-		 * @throws ArgumentException if the object held by the
-		 *                                  tagged object cannot be converted.
-		 */
-		public static MQVuserKeyingMaterial GetInstance(
-			Asn1TaggedObject	obj,
-			bool				isExplicit)
-		{
-			return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit));
-		}
-
-		/**
-		 * return an AuthEnvelopedData object from the given object.
-		 *
-		 * @param obj the object we want converted.
-		 * @throws ArgumentException if the object cannot be converted.
-		 */
-		public static MQVuserKeyingMaterial GetInstance(
-			object	obj)
-		{
-			if (obj == null || obj is MQVuserKeyingMaterial)
-			{
-				return (MQVuserKeyingMaterial)obj;
-			}
-
-			if (obj is Asn1Sequence)
-			{
-				return new MQVuserKeyingMaterial((Asn1Sequence)obj);
-			}
-
-            throw new ArgumentException("Invalid MQVuserKeyingMaterial: " + Platform.GetTypeName(obj));
-		}
-		
-		public OriginatorPublicKey EphemeralPublicKey
+        public OriginatorPublicKey EphemeralPublicKey
 		{
 			get { return ephemeralPublicKey; }
 		}
diff --git a/crypto/src/cms/CMSUtils.cs b/crypto/src/cms/CMSUtils.cs
index 56509ed7f..d84c0afd7 100644
--- a/crypto/src/cms/CMSUtils.cs
+++ b/crypto/src/cms/CMSUtils.cs
@@ -187,7 +187,7 @@ namespace Org.BouncyCastle.Cms
 		internal static IssuerAndSerialNumber GetIssuerAndSerialNumber(X509Certificate cert)
 		{
 			TbsCertificateStructure tbsCert = GetTbsCertificateStructure(cert);
-			return new IssuerAndSerialNumber(tbsCert.Issuer, tbsCert.SerialNumber.Value);
+			return new IssuerAndSerialNumber(tbsCert.Issuer, tbsCert.SerialNumber);
 		}
 
         internal static Asn1.Cms.AttributeTable ParseAttributeTable(Asn1SetParser parser)
diff --git a/crypto/src/cms/KeyTransRecipientInfoGenerator.cs b/crypto/src/cms/KeyTransRecipientInfoGenerator.cs
index 9a2cbc5b0..a998ac90f 100644
--- a/crypto/src/cms/KeyTransRecipientInfoGenerator.cs
+++ b/crypto/src/cms/KeyTransRecipientInfoGenerator.cs
@@ -19,7 +19,7 @@ namespace Org.BouncyCastle.Cms
         private Asn1OctetString m_subjectKeyIdentifier;
 
         public KeyTransRecipientInfoGenerator(X509Certificate recipCert, IKeyWrapper keyWrapper)
-            : this(new IssuerAndSerialNumber(recipCert.IssuerDN, new DerInteger(recipCert.SerialNumber)), keyWrapper)
+            : this(new IssuerAndSerialNumber(recipCert.CertificateStructure), keyWrapper)
         {
         }
 
diff --git a/crypto/src/cms/SignerInfoGenerator.cs b/crypto/src/cms/SignerInfoGenerator.cs
index 2fa185885..04c437614 100644
--- a/crypto/src/cms/SignerInfoGenerator.cs
+++ b/crypto/src/cms/SignerInfoGenerator.cs
@@ -130,8 +130,7 @@ namespace Org.BouncyCastle.Cms
          */
         public SignerInfoGenerator Build(ISignatureFactory contentSigner, X509Certificate certificate)
         {
-            SignerIdentifier sigId = new SignerIdentifier(new IssuerAndSerialNumber(certificate.IssuerDN,
-                new DerInteger(certificate.SerialNumber)));
+            SignerIdentifier sigId = new SignerIdentifier(new IssuerAndSerialNumber(certificate.CertificateStructure));
 
             SignerInfoGenerator sigInfoGen = CreateGenerator(contentSigner, sigId);
 
diff --git a/crypto/src/crypto/operators/CmsKeyTransRecipientInfoGenerator.cs b/crypto/src/crypto/operators/CmsKeyTransRecipientInfoGenerator.cs
index 0165f6af0..e733bb018 100644
--- a/crypto/src/crypto/operators/CmsKeyTransRecipientInfoGenerator.cs
+++ b/crypto/src/crypto/operators/CmsKeyTransRecipientInfoGenerator.cs
@@ -14,7 +14,7 @@ namespace Org.BouncyCastle.Operators
         : KeyTransRecipientInfoGenerator
     {
         public CmsKeyTransRecipientInfoGenerator(X509Certificate recipCert, IKeyWrapper keyWrapper)
-            : base(new Asn1.Cms.IssuerAndSerialNumber(recipCert.IssuerDN, new DerInteger(recipCert.SerialNumber)), keyWrapper)
+            : base(new Asn1.Cms.IssuerAndSerialNumber(recipCert.CertificateStructure), keyWrapper)
         {
         }