summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crypto/src/asn1/esf/CertificateValues.cs47
-rw-r--r--crypto/src/asn1/esf/CommitmentTypeIdentifier.cs4
-rw-r--r--crypto/src/asn1/esf/CommitmentTypeIndication.cs85
-rw-r--r--crypto/src/asn1/esf/CommitmentTypeQualifier.cs111
-rw-r--r--crypto/src/asn1/esf/CompleteCertificateRefs.cs54
-rw-r--r--crypto/src/asn1/esf/CompleteRevocationRefs.cs54
-rw-r--r--crypto/src/asn1/esf/CrlIdentifier.cs65
-rw-r--r--crypto/src/asn1/esf/CrlListID.cs78
-rw-r--r--crypto/src/asn1/esf/CrlOcspRef.cs117
-rw-r--r--crypto/src/asn1/esf/CrlValidatedID.cs107
-rw-r--r--crypto/src/asn1/esf/ESFAttributes.cs4
-rw-r--r--crypto/src/asn1/esf/OcspIdentifier.cs92
-rw-r--r--crypto/src/asn1/esf/OcspListID.cs86
-rw-r--r--crypto/src/asn1/esf/OcspResponsesID.cs115
-rw-r--r--crypto/src/asn1/esf/OtherCertID.cs88
-rw-r--r--crypto/src/asn1/esf/OtherHash.cs101
-rw-r--r--crypto/src/asn1/esf/OtherHashAlgAndValue.cs114
-rw-r--r--crypto/src/asn1/esf/OtherRevRefs.cs102
-rw-r--r--crypto/src/asn1/esf/OtherRevVals.cs110
-rw-r--r--crypto/src/asn1/esf/OtherSigningCertificate.cs72
-rw-r--r--crypto/src/asn1/esf/RevocationValues.cs122
-rw-r--r--crypto/src/asn1/esf/SigPolicyQualifierInfo.cs75
-rw-r--r--crypto/src/asn1/esf/SignaturePolicyId.cs119
-rw-r--r--crypto/src/asn1/esf/SignaturePolicyIdentifier.cs55
-rw-r--r--crypto/src/asn1/esf/SignerAttribute.cs66
-rw-r--r--crypto/src/asn1/esf/SignerLocation.cs149
26 files changed, 885 insertions, 1307 deletions
diff --git a/crypto/src/asn1/esf/CertificateValues.cs b/crypto/src/asn1/esf/CertificateValues.cs
index 96088209f..384094511 100644
--- a/crypto/src/asn1/esf/CertificateValues.cs
+++ b/crypto/src/asn1/esf/CertificateValues.cs
@@ -2,21 +2,18 @@ using System;
 using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1.X509;
-using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Asn1.Esf
 {
-	/// <remarks>
-	/// RFC 3126: 4.3.1 Certificate Values Attribute Definition
-	/// <code>
-	/// CertificateValues ::= SEQUENCE OF Certificate
-	/// </code>
-	/// </remarks>
-	public class CertificateValues
+    /// <remarks>
+    /// RFC 3126: 4.3.1 Certificate Values Attribute Definition
+    /// <code>
+    /// CertificateValues ::= SEQUENCE OF Certificate
+    /// </code>
+    /// </remarks>
+    public class CertificateValues
 		: Asn1Encodable
 	{
-		private readonly Asn1Sequence m_certificates;
-
 		public static CertificateValues GetInstance(object obj)
 		{
             if (obj == null)
@@ -28,26 +25,23 @@ namespace Org.BouncyCastle.Asn1.Esf
 
         public static CertificateValues GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
         {
-            return GetInstance(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+            return new CertificateValues(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
         }
 
+        private readonly Asn1Sequence m_certificates;
+
         private CertificateValues(Asn1Sequence seq)
 		{
-			if (seq == null)
-				throw new ArgumentNullException(nameof(seq));
-
-			// Validate
-            seq.MapElements(element => X509CertificateStructure.GetInstance(element.ToAsn1Object()));
-
 			m_certificates = seq;
-		}
+            m_certificates.MapElements(X509CertificateStructure.GetInstance); // Validate
+        }
 
-		public CertificateValues(params X509CertificateStructure[] certificates)
+        public CertificateValues(params X509CertificateStructure[] certificates)
 		{
 			if (certificates == null)
 				throw new ArgumentNullException(nameof(certificates));
 
-			m_certificates = new DerSequence(certificates);
+			m_certificates = DerSequence.FromElements(certificates);
 		}
 
 		public CertificateValues(IEnumerable<X509CertificateStructure> certificates)
@@ -55,17 +49,12 @@ namespace Org.BouncyCastle.Asn1.Esf
 			if (certificates == null)
                 throw new ArgumentNullException(nameof(certificates));
 
-            m_certificates = new DerSequence(Asn1EncodableVector.FromEnumerable(certificates));
+            m_certificates = DerSequence.FromVector(Asn1EncodableVector.FromEnumerable(certificates));
 		}
 
-		public X509CertificateStructure[] GetCertificates()
-		{
-			return m_certificates.MapElements(element => X509CertificateStructure.GetInstance(element.ToAsn1Object()));
-		}
+		public X509CertificateStructure[] GetCertificates() =>
+			m_certificates.MapElements(X509CertificateStructure.GetInstance);
 
-		public override Asn1Object ToAsn1Object()
-		{
-			return m_certificates;
-		}
+		public override Asn1Object ToAsn1Object() => m_certificates;
  	}
 }
diff --git a/crypto/src/asn1/esf/CommitmentTypeIdentifier.cs b/crypto/src/asn1/esf/CommitmentTypeIdentifier.cs
index 65cd45b4a..8689110e8 100644
--- a/crypto/src/asn1/esf/CommitmentTypeIdentifier.cs
+++ b/crypto/src/asn1/esf/CommitmentTypeIdentifier.cs
@@ -1,10 +1,8 @@
-using System;
-
-using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.Pkcs;
 
 namespace Org.BouncyCastle.Asn1.Esf
 {
+    // TODO[api] Make static
     public abstract class CommitmentTypeIdentifier
     {
         public static readonly DerObjectIdentifier ProofOfOrigin = PkcsObjectIdentifiers.IdCtiEtsProofOfOrigin;
diff --git a/crypto/src/asn1/esf/CommitmentTypeIndication.cs b/crypto/src/asn1/esf/CommitmentTypeIndication.cs
index ecdb10067..13dc01d84 100644
--- a/crypto/src/asn1/esf/CommitmentTypeIndication.cs
+++ b/crypto/src/asn1/esf/CommitmentTypeIndication.cs
@@ -1,76 +1,60 @@
 using System;
 
-using Org.BouncyCastle.Utilities;
-
 namespace Org.BouncyCastle.Asn1.Esf
 {
     public class CommitmentTypeIndication
         : Asn1Encodable
     {
-        private readonly DerObjectIdentifier	commitmentTypeId;
-        private readonly Asn1Sequence			commitmentTypeQualifier;
-
-		public static CommitmentTypeIndication GetInstance(
-			object obj)
-		{
-			if (obj == null || obj is CommitmentTypeIndication)
-				return (CommitmentTypeIndication) obj;
+        public static CommitmentTypeIndication GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is CommitmentTypeIndication commitmentTypeIndication)
+                return commitmentTypeIndication;
+#pragma warning disable CS0618 // Type or member is obsolete
+            return new CommitmentTypeIndication(Asn1Sequence.GetInstance(obj));
+#pragma warning restore CS0618 // Type or member is obsolete
+        }
 
-			if (obj is Asn1Sequence)
-				return new CommitmentTypeIndication((Asn1Sequence) obj);
+        public static CommitmentTypeIndication GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+#pragma warning disable CS0618 // Type or member is obsolete
+            return new CommitmentTypeIndication(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+#pragma warning restore CS0618 // Type or member is obsolete
+        }
 
-			throw new ArgumentException(
-				"Unknown object in 'CommitmentTypeIndication' factory: "
-                    + Platform.GetTypeName(obj),
-				"obj");
-		}
+        private readonly DerObjectIdentifier m_commitmentTypeId;
+        private readonly Asn1Sequence m_commitmentTypeQualifier;
 
-		public CommitmentTypeIndication(
-            Asn1Sequence seq)
+        [Obsolete("Use 'GetInstance' instead")]
+        public CommitmentTypeIndication(Asn1Sequence seq)
         {
-			if (seq == null)
-				throw new ArgumentNullException("seq");
-			if (seq.Count < 1 || seq.Count > 2)
-				throw new ArgumentException("Bad sequence size: " + seq.Count, "seq");
+            int count = seq.Count;
+			if (count < 1 || count > 2)
+				throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
 
-			this.commitmentTypeId = (DerObjectIdentifier) seq[0].ToAsn1Object();
+			m_commitmentTypeId = DerObjectIdentifier.GetInstance(seq[0]);
 
-			if (seq.Count > 1)
+			if (count > 1)
             {
-                this.commitmentTypeQualifier = (Asn1Sequence) seq[1].ToAsn1Object();
+                m_commitmentTypeQualifier = Asn1Sequence.GetInstance(seq[1]);
             }
         }
 
-		public CommitmentTypeIndication(
-            DerObjectIdentifier commitmentTypeId)
+		public CommitmentTypeIndication(DerObjectIdentifier commitmentTypeId)
 			: this(commitmentTypeId, null)
         {
         }
 
-		public CommitmentTypeIndication(
-            DerObjectIdentifier	commitmentTypeId,
-            Asn1Sequence		commitmentTypeQualifier)
+		public CommitmentTypeIndication(DerObjectIdentifier commitmentTypeId, Asn1Sequence commitmentTypeQualifier)
         {
-			if (commitmentTypeId == null)
-				throw new ArgumentNullException("commitmentTypeId");
-
-			this.commitmentTypeId = commitmentTypeId;
-
-			if (commitmentTypeQualifier != null)
-			{
-				this.commitmentTypeQualifier = commitmentTypeQualifier;
-			}
+			m_commitmentTypeId = commitmentTypeId ?? throw new ArgumentNullException(nameof(commitmentTypeId));
+            m_commitmentTypeQualifier = commitmentTypeQualifier;
         }
 
-		public DerObjectIdentifier CommitmentTypeID
-		{
-			get { return commitmentTypeId; }
-		}
+        public DerObjectIdentifier CommitmentTypeID => m_commitmentTypeId;
 
-		public Asn1Sequence CommitmentTypeQualifier
-		{
-			get { return commitmentTypeQualifier; }
-		}
+        public Asn1Sequence CommitmentTypeQualifier => m_commitmentTypeQualifier;
 
 		/**
         * <pre>
@@ -82,8 +66,9 @@ namespace Org.BouncyCastle.Asn1.Esf
         */
         public override Asn1Object ToAsn1Object()
         {
-            Asn1EncodableVector v = new Asn1EncodableVector(commitmentTypeId);
-            v.AddOptional(commitmentTypeQualifier);
+            Asn1EncodableVector v = new Asn1EncodableVector(2);
+            v.Add(m_commitmentTypeId);
+            v.AddOptional(m_commitmentTypeQualifier);
 			return new DerSequence(v);
         }
     }
diff --git a/crypto/src/asn1/esf/CommitmentTypeQualifier.cs b/crypto/src/asn1/esf/CommitmentTypeQualifier.cs
index acf19f9f6..dd818613e 100644
--- a/crypto/src/asn1/esf/CommitmentTypeQualifier.cs
+++ b/crypto/src/asn1/esf/CommitmentTypeQualifier.cs
@@ -1,7 +1,5 @@
 using System;
 
-using Org.BouncyCastle.Utilities;
-
 namespace Org.BouncyCastle.Asn1.Esf
 {
     /**
@@ -16,39 +14,48 @@ namespace Org.BouncyCastle.Asn1.Esf
     public class CommitmentTypeQualifier
         : Asn1Encodable
     {
-        private readonly DerObjectIdentifier	commitmentTypeIdentifier;
-        private readonly Asn1Object				qualifier;
+        public static CommitmentTypeQualifier GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is CommitmentTypeQualifier commitmentTypeQualifier)
+                return commitmentTypeQualifier;
+#pragma warning disable CS0618 // Type or member is obsolete
+            return new CommitmentTypeQualifier(Asn1Sequence.GetInstance(obj));
+#pragma warning restore CS0618 // Type or member is obsolete
+        }
+
+        public static CommitmentTypeQualifier GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+#pragma warning disable CS0618 // Type or member is obsolete
+            return new CommitmentTypeQualifier(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+#pragma warning restore CS0618 // Type or member is obsolete
+        }
+
+        private readonly DerObjectIdentifier m_commitmentTypeIdentifier;
+        private readonly Asn1Encodable m_qualifier;
 
         /**
-        * Creates a new <code>CommitmentTypeQualifier</code> instance.
-        *
-        * @param commitmentTypeIdentifier a <code>CommitmentTypeIdentifier</code> value
-        */
-        public CommitmentTypeQualifier(
-            DerObjectIdentifier commitmentTypeIdentifier)
+         * Creates a new <code>CommitmentTypeQualifier</code> instance.
+         *
+         * @param commitmentTypeIdentifier a <code>CommitmentTypeIdentifier</code> value
+         */
+        public CommitmentTypeQualifier(DerObjectIdentifier commitmentTypeIdentifier)
             : this(commitmentTypeIdentifier, null)
         {
         }
 
-    /**
-        * Creates a new <code>CommitmentTypeQualifier</code> instance.
-        *
-        * @param commitmentTypeIdentifier a <code>CommitmentTypeIdentifier</code> value
-        * @param qualifier the qualifier, defined by the above field.
-        */
-        public CommitmentTypeQualifier(
-            DerObjectIdentifier	commitmentTypeIdentifier,
-            Asn1Encodable		qualifier)
+        /**
+         * Creates a new <code>CommitmentTypeQualifier</code> instance.
+         *
+         * @param commitmentTypeIdentifier a <code>CommitmentTypeIdentifier</code> value
+         * @param qualifier the qualifier, defined by the above field.
+         */
+        public CommitmentTypeQualifier(DerObjectIdentifier commitmentTypeIdentifier, Asn1Encodable qualifier)
         {
-			if (commitmentTypeIdentifier == null)
-				throw new ArgumentNullException("commitmentTypeIdentifier");
-
-			this.commitmentTypeIdentifier = commitmentTypeIdentifier;
-
-			if (qualifier != null)
-			{
-				this.qualifier = qualifier.ToAsn1Object();
-			}
+			m_commitmentTypeIdentifier = commitmentTypeIdentifier
+                ?? throw new ArgumentNullException(nameof(commitmentTypeIdentifier));
+            m_qualifier = qualifier;
         }
 
         /**
@@ -57,46 +64,27 @@ namespace Org.BouncyCastle.Asn1.Esf
         * @param as <code>CommitmentTypeQualifier</code> structure
         * encoded as an Asn1Sequence.
         */
-        public CommitmentTypeQualifier(
-            Asn1Sequence seq)
+        [Obsolete("Use 'GetInstance' instead")]
+        public CommitmentTypeQualifier(Asn1Sequence seq)
         {
-			if (seq == null)
-				throw new ArgumentNullException("seq");
-			if (seq.Count < 1 || seq.Count > 2)
-				throw new ArgumentException("Bad sequence size: " + seq.Count, "seq");
+            int count = seq.Count;
+			if (count < 1 || count > 2)
+				throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
 
-			commitmentTypeIdentifier = (DerObjectIdentifier) seq[0].ToAsn1Object();
+			m_commitmentTypeIdentifier = DerObjectIdentifier.GetInstance(seq[0]);
 
-			if (seq.Count > 1)
+			if (count > 1)
             {
-                qualifier = seq[1].ToAsn1Object();
+                m_qualifier = seq[1];
             }
         }
 
-		public static CommitmentTypeQualifier GetInstance(
-			object obj)
-		{
-			if (obj == null || obj is CommitmentTypeQualifier)
-				return (CommitmentTypeQualifier) obj;
-
-			if (obj is Asn1Sequence)
-				return new CommitmentTypeQualifier((Asn1Sequence) obj);
+        public DerObjectIdentifier CommitmentTypeIdentifier => m_commitmentTypeIdentifier;
 
-			throw new ArgumentException(
-				"Unknown object in 'CommitmentTypeQualifier' factory: "
-                    + Platform.GetTypeName(obj),
-				"obj");
-		}
-
-		public DerObjectIdentifier CommitmentTypeIdentifier
-		{
-			get { return commitmentTypeIdentifier; }
-		}
+        public Asn1Encodable QualifierData => m_qualifier;
 
-		public Asn1Object Qualifier
-		{
-			get { return qualifier; }
-		}
+        [Obsolete("Use 'QualifierData' instead")]
+        public Asn1Object Qualifier => m_qualifier?.ToAsn1Object();
 
 		/**
         * Returns a DER-encodable representation of this instance.
@@ -105,8 +93,9 @@ namespace Org.BouncyCastle.Asn1.Esf
         */
 		public override Asn1Object ToAsn1Object()
 		{
-			Asn1EncodableVector v = new Asn1EncodableVector(commitmentTypeIdentifier);
-            v.AddOptional(qualifier);
+            Asn1EncodableVector v = new Asn1EncodableVector(2);
+            v.Add(m_commitmentTypeIdentifier);
+            v.AddOptional(m_qualifier);
 			return new DerSequence(v);
 		}
     }
diff --git a/crypto/src/asn1/esf/CompleteCertificateRefs.cs b/crypto/src/asn1/esf/CompleteCertificateRefs.cs
index 24727dc25..4e8f122ca 100644
--- a/crypto/src/asn1/esf/CompleteCertificateRefs.cs
+++ b/crypto/src/asn1/esf/CompleteCertificateRefs.cs
@@ -1,45 +1,37 @@
 using System;
 using System.Collections.Generic;
 
-using Org.BouncyCastle.Utilities;
-
 namespace Org.BouncyCastle.Asn1.Esf
 {
-	/// <remarks>
-	/// RFC 3126: 4.2.1 Complete Certificate Refs Attribute Definition
-	/// <code>
-	/// CompleteCertificateRefs ::= SEQUENCE OF OtherCertID
-	/// </code>
-	/// </remarks>
-	public class CompleteCertificateRefs
+    /// <remarks>
+    /// RFC 3126: 4.2.1 Complete Certificate Refs Attribute Definition
+    /// <code>
+    /// CompleteCertificateRefs ::= SEQUENCE OF OtherCertID
+    /// </code>
+    /// </remarks>
+    public class CompleteCertificateRefs
 		: Asn1Encodable
 	{
-		private readonly Asn1Sequence m_otherCertIDs;
-
 		public static CompleteCertificateRefs GetInstance(object obj)
 		{
 			if (obj == null)
 				return null;
-
             if (obj is CompleteCertificateRefs completeCertificateRefs)
 				return completeCertificateRefs;
-
-			if (obj is Asn1Sequence asn1Sequence)
-				return new CompleteCertificateRefs(asn1Sequence);
-
-			throw new ArgumentException("Unknown object in 'CompleteCertificateRefs' factory: " + Platform.GetTypeName(obj),
-				nameof(obj));
+			return new CompleteCertificateRefs(Asn1Sequence.GetInstance(obj));
 		}
 
-		private CompleteCertificateRefs(Asn1Sequence seq)
-		{
-			if (seq == null)
-				throw new ArgumentNullException(nameof(seq));
+        public static CompleteCertificateRefs GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new CompleteCertificateRefs(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
 
-            // Validate
-            seq.MapElements(element => OtherCertID.GetInstance(element.ToAsn1Object()));
+        private readonly Asn1Sequence m_otherCertIDs;
 
+        private CompleteCertificateRefs(Asn1Sequence seq)
+		{
             m_otherCertIDs = seq;
+            m_otherCertIDs.MapElements(OtherCertID.GetInstance); // Validate
 		}
 
 		public CompleteCertificateRefs(params OtherCertID[] otherCertIDs)
@@ -47,7 +39,7 @@ namespace Org.BouncyCastle.Asn1.Esf
 			if (otherCertIDs == null)
 				throw new ArgumentNullException(nameof(otherCertIDs));
 
-			m_otherCertIDs = new DerSequence(otherCertIDs);
+			m_otherCertIDs = DerSequence.FromElements(otherCertIDs);
 		}
 
 		public CompleteCertificateRefs(IEnumerable<OtherCertID> otherCertIDs)
@@ -55,17 +47,11 @@ namespace Org.BouncyCastle.Asn1.Esf
 			if (otherCertIDs == null)
                 throw new ArgumentNullException(nameof(otherCertIDs));
 
-            m_otherCertIDs = new DerSequence(Asn1EncodableVector.FromEnumerable(otherCertIDs));
+            m_otherCertIDs = DerSequence.FromVector(Asn1EncodableVector.FromEnumerable(otherCertIDs));
 		}
 
-		public OtherCertID[] GetOtherCertIDs()
-		{
-            return m_otherCertIDs.MapElements(element => OtherCertID.GetInstance(element.ToAsn1Object()));
-		}
+		public OtherCertID[] GetOtherCertIDs() => m_otherCertIDs.MapElements(OtherCertID.GetInstance);
 
-		public override Asn1Object ToAsn1Object()
-		{
-			return m_otherCertIDs;
-		}
+		public override Asn1Object ToAsn1Object() => m_otherCertIDs;
 	}
 }
diff --git a/crypto/src/asn1/esf/CompleteRevocationRefs.cs b/crypto/src/asn1/esf/CompleteRevocationRefs.cs
index 2c120f0f9..82ac6beab 100644
--- a/crypto/src/asn1/esf/CompleteRevocationRefs.cs
+++ b/crypto/src/asn1/esf/CompleteRevocationRefs.cs
@@ -1,45 +1,37 @@
 using System;
 using System.Collections.Generic;
 
-using Org.BouncyCastle.Utilities;
-
 namespace Org.BouncyCastle.Asn1.Esf
 {
-	/// <remarks>
-	/// RFC 3126: 4.2.2 Complete Revocation Refs Attribute Definition
-	/// <code>
-	/// CompleteRevocationRefs ::= SEQUENCE OF CrlOcspRef
-	/// </code>
-	/// </remarks>
-	public class CompleteRevocationRefs
+    /// <remarks>
+    /// RFC 3126: 4.2.2 Complete Revocation Refs Attribute Definition
+    /// <code>
+    /// CompleteRevocationRefs ::= SEQUENCE OF CrlOcspRef
+    /// </code>
+    /// </remarks>
+    public class CompleteRevocationRefs
 		: Asn1Encodable
 	{
-		private readonly Asn1Sequence m_crlOcspRefs;
-
 		public static CompleteRevocationRefs GetInstance(object obj)
 		{
 			if (obj == null)
 				return null;
-
 			if (obj is CompleteRevocationRefs completeRevocationRefs)
 				return completeRevocationRefs;
-
-			if (obj is Asn1Sequence asn1Sequence)
-				return new CompleteRevocationRefs(asn1Sequence);
-
-			throw new ArgumentException("Unknown object in 'CompleteRevocationRefs' factory: " + Platform.GetTypeName(obj),
-				nameof(obj));
+			return new CompleteRevocationRefs(Asn1Sequence.GetInstance(obj));
 		}
 
-		private CompleteRevocationRefs(Asn1Sequence seq)
-		{
-			if (seq == null)
-				throw new ArgumentNullException(nameof(seq));
+        public static CompleteRevocationRefs GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new CompleteRevocationRefs(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
 
-            // Validate
-            seq.MapElements(element => CrlOcspRef.GetInstance(element.ToAsn1Object()));
+        private readonly Asn1Sequence m_crlOcspRefs;
 
+        private CompleteRevocationRefs(Asn1Sequence seq)
+		{
 			m_crlOcspRefs = seq;
+            m_crlOcspRefs.MapElements(CrlOcspRef.GetInstance); // Validate
 		}
 
 		public CompleteRevocationRefs(params CrlOcspRef[] crlOcspRefs)
@@ -47,7 +39,7 @@ namespace Org.BouncyCastle.Asn1.Esf
 			if (crlOcspRefs == null)
 				throw new ArgumentNullException(nameof(crlOcspRefs));
 
-			m_crlOcspRefs = new DerSequence(crlOcspRefs);
+			m_crlOcspRefs = DerSequence.FromElements(crlOcspRefs);
 		}
 
 		public CompleteRevocationRefs(IEnumerable<CrlOcspRef> crlOcspRefs)
@@ -55,17 +47,11 @@ namespace Org.BouncyCastle.Asn1.Esf
 			if (crlOcspRefs == null)
                 throw new ArgumentNullException(nameof(crlOcspRefs));
 
-            m_crlOcspRefs = new DerSequence(Asn1EncodableVector.FromEnumerable(crlOcspRefs));
+            m_crlOcspRefs = DerSequence.FromVector(Asn1EncodableVector.FromEnumerable(crlOcspRefs));
 		}
 
-		public CrlOcspRef[] GetCrlOcspRefs()
-		{
-            return m_crlOcspRefs.MapElements(element => CrlOcspRef.GetInstance(element.ToAsn1Object()));
-		}
+		public CrlOcspRef[] GetCrlOcspRefs() => m_crlOcspRefs.MapElements(CrlOcspRef.GetInstance);
 
-		public override Asn1Object ToAsn1Object()
-		{
-			return m_crlOcspRefs;
-		}
+		public override Asn1Object ToAsn1Object() => m_crlOcspRefs;
 	}
 }
diff --git a/crypto/src/asn1/esf/CrlIdentifier.cs b/crypto/src/asn1/esf/CrlIdentifier.cs
index 9521d6a08..24ee7e17e 100644
--- a/crypto/src/asn1/esf/CrlIdentifier.cs
+++ b/crypto/src/asn1/esf/CrlIdentifier.cs
@@ -5,24 +5,20 @@ using Org.BouncyCastle.Math;
 
 namespace Org.BouncyCastle.Asn1.Esf
 {
-	/// <remarks>
-	/// RFC 3126: 4.2.2 Complete Revocation Refs Attribute Definition
-	/// <code>
-	/// CrlIdentifier ::= SEQUENCE 
-	/// {
-	/// 	crlissuer		Name,
-	/// 	crlIssuedTime	UTCTime,
-	/// 	crlNumber		INTEGER OPTIONAL
-	/// }
-	/// </code>
-	/// </remarks>
-	public class CrlIdentifier
+    /// <remarks>
+    /// RFC 3126: 4.2.2 Complete Revocation Refs Attribute Definition
+    /// <code>
+    /// CrlIdentifier ::= SEQUENCE 
+    /// {
+    /// 	crlissuer		Name,
+    /// 	crlIssuedTime	UTCTime,
+    /// 	crlNumber		INTEGER OPTIONAL
+    /// }
+    /// </code>
+    /// </remarks>
+    public class CrlIdentifier
 		: Asn1Encodable
 	{
-		private readonly X509Name m_crlIssuer;
-		private readonly Asn1UtcTime m_crlIssuedTime;
-		private readonly DerInteger m_crlNumber;
-
 		public static CrlIdentifier GetInstance(object obj)
 		{
 			if (obj == null)
@@ -37,22 +33,25 @@ namespace Org.BouncyCastle.Asn1.Esf
             return GetInstance(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
         }
 
+        private readonly X509Name m_crlIssuer;
+        private readonly Asn1UtcTime m_crlIssuedTime;
+        private readonly DerInteger m_crlNumber;
+
         private CrlIdentifier(Asn1Sequence seq)
 		{
-			if (seq == null)
-				throw new ArgumentNullException(nameof(seq));
-			if (seq.Count < 2 || seq.Count > 3)
-				throw new ArgumentException("Bad sequence size: " + seq.Count, nameof(seq));
+			int count = seq.Count;
+			if (count < 2 || count > 3)
+				throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
 
-			this.m_crlIssuer = X509Name.GetInstance(seq[0]);
-			this.m_crlIssuedTime = Asn1UtcTime.GetInstance(seq[1]);
+			m_crlIssuer = X509Name.GetInstance(seq[0]);
+			m_crlIssuedTime = Asn1UtcTime.GetInstance(seq[1]);
 
             // Validate crlIssuedTime is in the appropriate year range
             m_crlIssuedTime.ToDateTime(2049);
 
-			if (seq.Count > 2)
+			if (count > 2)
 			{
-				this.m_crlNumber = DerInteger.GetInstance(seq[2]);
+				m_crlNumber = DerInteger.GetInstance(seq[2]);
 			}
 		}
 
@@ -85,24 +84,16 @@ namespace Org.BouncyCastle.Asn1.Esf
             m_crlIssuedTime.ToDateTime(2049);
         }
 
-        public X509Name CrlIssuer
-		{
-			get { return m_crlIssuer; }
-		}
+        public X509Name CrlIssuer => m_crlIssuer;
 
-		public DateTime CrlIssuedTime
-		{
-			get { return m_crlIssuedTime.ToDateTime(2049); }
-		}
+		public DateTime CrlIssuedTime => m_crlIssuedTime.ToDateTime(2049);
 
-		public BigInteger CrlNumber
-		{
-			get { return m_crlNumber?.Value; }
-		}
+		public BigInteger CrlNumber => m_crlNumber?.Value;
 
 		public override Asn1Object ToAsn1Object()
 		{
-			var v = new Asn1EncodableVector(m_crlIssuer.ToAsn1Object(), m_crlIssuedTime);
+			var v = new Asn1EncodableVector(3);
+			v.Add(m_crlIssuer, m_crlIssuedTime);
             v.AddOptional(m_crlNumber);
 			return new DerSequence(v);
 		}
diff --git a/crypto/src/asn1/esf/CrlListID.cs b/crypto/src/asn1/esf/CrlListID.cs
index 1ee58aebc..ef49f9f4f 100644
--- a/crypto/src/asn1/esf/CrlListID.cs
+++ b/crypto/src/asn1/esf/CrlListID.cs
@@ -1,50 +1,44 @@
 using System;
 using System.Collections.Generic;
 
-using Org.BouncyCastle.Utilities;
-
 namespace Org.BouncyCastle.Asn1.Esf
 {
-	/// <remarks>
-	/// RFC 3126: 4.2.2 Complete Revocation Refs Attribute Definition
-	/// <code>
-	/// CRLListID ::= SEQUENCE 
-	/// {
-	///		crls	SEQUENCE OF CrlValidatedID
-	/// }
-	/// </code>
-	/// </remarks>
-	public class CrlListID
+    /// <remarks>
+    /// RFC 3126: 4.2.2 Complete Revocation Refs Attribute Definition
+    /// <code>
+    /// CRLListID ::= SEQUENCE 
+    /// {
+    ///		crls	SEQUENCE OF CrlValidatedID
+    /// }
+    /// </code>
+    /// </remarks>
+    public class CrlListID
 		: Asn1Encodable
 	{
-		private readonly Asn1Sequence m_crls;
-
-		public static CrlListID GetInstance(object obj)
-		{
-			if (obj == null)
-				return null;
+        public static CrlListID GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is CrlListID crlListID)
+                return crlListID;
+            return new CrlListID(Asn1Sequence.GetInstance(obj));
+        }
 
-			if (obj is CrlListID crlListID)
-				return crlListID;
+        public static CrlListID GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new CrlListID(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
 
-			if (obj is Asn1Sequence asn1Sequence)
-				return new CrlListID(asn1Sequence);
-
-			throw new ArgumentException("Unknown object in 'CrlListID' factory: " + Platform.GetTypeName(obj),
-				nameof(obj));
-		}
+        private readonly Asn1Sequence m_crls;
 
-		private CrlListID(Asn1Sequence seq)
+        private CrlListID(Asn1Sequence seq)
 		{
-			if (seq == null)
-				throw new ArgumentNullException(nameof(seq));
-			if (seq.Count != 1)
-				throw new ArgumentException("Bad sequence size: " + seq.Count, nameof(seq));
+			int count = seq.Count;
+			if (count != 1)
+				throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
 
-			m_crls = (Asn1Sequence)seq[0].ToAsn1Object();
-
-			// Validate
-			m_crls.MapElements(element => CrlValidatedID.GetInstance(element.ToAsn1Object()));
+			m_crls = Asn1Sequence.GetInstance(seq[0]);
+			m_crls.MapElements(CrlValidatedID.GetInstance); // Validate
 		}
 
 		public CrlListID(params CrlValidatedID[] crls)
@@ -52,7 +46,7 @@ namespace Org.BouncyCastle.Asn1.Esf
 			if (crls == null)
 				throw new ArgumentNullException(nameof(crls));
 
-			this.m_crls = new DerSequence(crls);
+			m_crls = DerSequence.FromElements(crls);
 		}
 
 		public CrlListID(IEnumerable<CrlValidatedID> crls)
@@ -60,17 +54,11 @@ namespace Org.BouncyCastle.Asn1.Esf
 			if (crls == null)
                 throw new ArgumentNullException(nameof(crls));
 
-            this.m_crls = new DerSequence(Asn1EncodableVector.FromEnumerable(crls));
+            m_crls = DerSequence.FromVector(Asn1EncodableVector.FromEnumerable(crls));
 		}
 
-		public CrlValidatedID[] GetCrls()
-		{
-            return m_crls.MapElements(element => CrlValidatedID.GetInstance(element.ToAsn1Object()));
-		}
+		public CrlValidatedID[] GetCrls() => m_crls.MapElements(CrlValidatedID.GetInstance);
 
-		public override Asn1Object ToAsn1Object()
-		{
-			return new DerSequence(m_crls);
-		}
+		public override Asn1Object ToAsn1Object() => new DerSequence(m_crls);
 	}
 }
diff --git a/crypto/src/asn1/esf/CrlOcspRef.cs b/crypto/src/asn1/esf/CrlOcspRef.cs
index 3b7598c9f..2d8dc1bc3 100644
--- a/crypto/src/asn1/esf/CrlOcspRef.cs
+++ b/crypto/src/asn1/esf/CrlOcspRef.cs
@@ -1,7 +1,5 @@
 using System;
 
-using Org.BouncyCastle.Utilities;
-
 namespace Org.BouncyCastle.Asn1.Esf
 {
 	/// <remarks>
@@ -17,95 +15,60 @@ namespace Org.BouncyCastle.Asn1.Esf
 	public class CrlOcspRef
 		: Asn1Encodable
 	{
-		private readonly CrlListID		crlids;
-		private readonly OcspListID		ocspids;
-		private readonly OtherRevRefs	otherRev;
-
-		public static CrlOcspRef GetInstance(
-			object obj)
+        public static CrlOcspRef GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is CrlOcspRef crlOcspRef)
+                return crlOcspRef;
+            return new CrlOcspRef(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static CrlOcspRef GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new CrlOcspRef(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
+
+        private readonly CrlListID m_crlids;
+        private readonly OcspListID m_ocspids;
+        private readonly OtherRevRefs m_otherRev;
+
+        private CrlOcspRef(Asn1Sequence seq)
 		{
-			if (obj == null || obj is CrlOcspRef)
-				return (CrlOcspRef) obj;
+            int count = seq.Count;
+            if (count < 0 || count > 3)
+                throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
 
-			if (obj is Asn1Sequence)
-				return new CrlOcspRef((Asn1Sequence) obj);
-
-			throw new ArgumentException(
-				"Unknown object in 'CrlOcspRef' factory: "
-                    + Platform.GetTypeName(obj),
-				"obj");
-		}
+            int pos = 0;
 
-		private CrlOcspRef(Asn1Sequence seq)
-		{
-			if (seq == null)
-				throw new ArgumentNullException("seq");
+			m_crlids = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 0, true, CrlListID.GetInstance);
+            m_ocspids = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 1, true, OcspListID.GetInstance);
+            m_otherRev = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 2, true, OtherRevRefs.GetInstance);
 
-			foreach (var element in seq)
-			{
-				var o = Asn1TaggedObject.GetInstance(element, Asn1Tags.ContextSpecific);
-				switch (o.TagNo)
-				{
-				case 0:
-					this.crlids = CrlListID.GetInstance(o.GetExplicitBaseObject());
-					break;
-				case 1:
-					this.ocspids = OcspListID.GetInstance(o.GetExplicitBaseObject());
-					break;
-				case 2:
-					this.otherRev = OtherRevRefs.GetInstance(o.GetExplicitBaseObject());
-					break;
-				default:
-					throw new ArgumentException("Illegal tag in CrlOcspRef", "seq");
-				}
-			}
+            if (pos != count)
+                throw new ArgumentException("Unexpected elements in sequence", nameof(seq));
 		}
 
-		public CrlOcspRef(
-			CrlListID		crlids,
-			OcspListID		ocspids,
-			OtherRevRefs	otherRev)
-		{
-			this.crlids = crlids;
-			this.ocspids = ocspids;
-			this.otherRev = otherRev;
+        public CrlOcspRef(CrlListID crlids, OcspListID ocspids, OtherRevRefs otherRev)
+        {
+            m_crlids = crlids;
+			m_ocspids = ocspids;
+			m_otherRev = otherRev;
 		}
 
-		public CrlListID CrlIDs
-		{
-			get { return crlids; }
-		}
+		public CrlListID CrlIDs => m_crlids;
 
-		public OcspListID OcspIDs
-		{
-			get { return ocspids; }
-		}
+		public OcspListID OcspIDs => m_ocspids;
 
-		public OtherRevRefs OtherRev
-		{
-			get { return otherRev; }
-		}
+		public OtherRevRefs OtherRev => m_otherRev;
 
 		public override Asn1Object ToAsn1Object()
 		{
 			Asn1EncodableVector v = new Asn1EncodableVector(3);
-
-			if (crlids != null)
-			{
-				v.Add(new DerTaggedObject(true, 0, crlids.ToAsn1Object()));
-			}
-
-			if (ocspids != null)
-			{
-				v.Add(new DerTaggedObject(true, 1, ocspids.ToAsn1Object()));
-			}
-
-			if (otherRev != null)
-			{
-				v.Add(new DerTaggedObject(true, 2, otherRev.ToAsn1Object()));
-			}
-
-			return new DerSequence(v);
+			v.AddOptionalTagged(true, 0, m_crlids);
+            v.AddOptionalTagged(true, 1, m_ocspids);
+            v.AddOptionalTagged(true, 2, m_otherRev);
+			return DerSequence.FromVector(v);
 		}
 	}
 }
diff --git a/crypto/src/asn1/esf/CrlValidatedID.cs b/crypto/src/asn1/esf/CrlValidatedID.cs
index e8cd17a19..0ce34a911 100644
--- a/crypto/src/asn1/esf/CrlValidatedID.cs
+++ b/crypto/src/asn1/esf/CrlValidatedID.cs
@@ -1,90 +1,69 @@
 using System;
 
-using Org.BouncyCastle.Utilities;
-
 namespace Org.BouncyCastle.Asn1.Esf
 {
-	/// <remarks>
-	/// RFC 3126: 4.2.2 Complete Revocation Refs Attribute Definition
-	/// <code>
-	/// CrlValidatedID ::= SEQUENCE {
-	///		crlHash			OtherHash,
-	///		crlIdentifier	CrlIdentifier OPTIONAL}
-	/// </code>
-	/// </remarks>
-	public class CrlValidatedID
+    /// <remarks>
+    /// RFC 3126: 4.2.2 Complete Revocation Refs Attribute Definition
+    /// <code>
+    /// CrlValidatedID ::= SEQUENCE {
+    ///		crlHash			OtherHash,
+    ///		crlIdentifier	CrlIdentifier OPTIONAL}
+    /// </code>
+    /// </remarks>
+    public class CrlValidatedID
 		: Asn1Encodable
 	{
-		private readonly OtherHash		crlHash;
-		private readonly CrlIdentifier	crlIdentifier;
-
-		public static CrlValidatedID GetInstance(
-			object obj)
+        public static CrlValidatedID GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is CrlValidatedID crlValidatedID)
+                return crlValidatedID;
+            return new CrlValidatedID(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static CrlValidatedID GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new CrlValidatedID(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
+
+        private readonly OtherHash m_crlHash;
+        private readonly CrlIdentifier m_crlIdentifier;
+
+        private CrlValidatedID(Asn1Sequence seq)
 		{
-			if (obj == null || obj is CrlValidatedID)
-				return (CrlValidatedID) obj;
+			int count = seq.Count;
+			if (count < 1 || count > 2)
+				throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
 
-			if (obj is Asn1Sequence)
-				return new CrlValidatedID((Asn1Sequence) obj);
+			m_crlHash = OtherHash.GetInstance(seq[0]);
 
-			throw new ArgumentException(
-				"Unknown object in 'CrlValidatedID' factory: "
-                    + Platform.GetTypeName(obj),
-				"obj");
-		}
-
-		private CrlValidatedID(
-			Asn1Sequence seq)
-		{
-			if (seq == null)
-				throw new ArgumentNullException("seq");
-			if (seq.Count < 1 || seq.Count > 2)
-				throw new ArgumentException("Bad sequence size: " + seq.Count, "seq");
-
-			this.crlHash = OtherHash.GetInstance(seq[0].ToAsn1Object());
-
-			if (seq.Count > 1)
+			if (count > 1)
 			{
-				this.crlIdentifier = CrlIdentifier.GetInstance(seq[1].ToAsn1Object());
+				m_crlIdentifier = CrlIdentifier.GetInstance(seq[1]);
 			}
 		}
 
-		public CrlValidatedID(
-			OtherHash crlHash)
+		public CrlValidatedID(OtherHash crlHash)
 			: this(crlHash, null)
 		{
 		}
 
-		public CrlValidatedID(
-			OtherHash		crlHash,
-			CrlIdentifier	crlIdentifier)
-		{
-			if (crlHash == null)
-				throw new ArgumentNullException("crlHash");
-
-			this.crlHash = crlHash;
-			this.crlIdentifier = crlIdentifier;
+        public CrlValidatedID(OtherHash crlHash, CrlIdentifier crlIdentifier)
+        {
+			m_crlHash = crlHash ?? throw new ArgumentNullException(nameof(crlHash));
+            m_crlIdentifier = crlIdentifier;
 		}
 
-		public OtherHash CrlHash
-		{
-			get { return crlHash; }
-		}
+		public OtherHash CrlHash => m_crlHash;
 
-		public CrlIdentifier CrlIdentifier
-		{
-			get { return crlIdentifier; }
-		}
+		public CrlIdentifier CrlIdentifier => m_crlIdentifier;
 
 		public override Asn1Object ToAsn1Object()
 		{
-			Asn1EncodableVector v = new Asn1EncodableVector(crlHash.ToAsn1Object());
-
-			if (crlIdentifier != null)
-			{
-				v.Add(crlIdentifier.ToAsn1Object());
-			}
-
+			Asn1EncodableVector v = new Asn1EncodableVector(2);
+			v.Add(m_crlHash);
+			v.AddOptional(m_crlIdentifier);
 			return new DerSequence(v);
 		}
 	}
diff --git a/crypto/src/asn1/esf/ESFAttributes.cs b/crypto/src/asn1/esf/ESFAttributes.cs
index 9401ffb8e..3a0d05b58 100644
--- a/crypto/src/asn1/esf/ESFAttributes.cs
+++ b/crypto/src/asn1/esf/ESFAttributes.cs
@@ -1,10 +1,8 @@
-using System;
-
-using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.Pkcs;
 
 namespace Org.BouncyCastle.Asn1.Esf
 {
+	// TODO[api] Make static
     public abstract class EsfAttributes
     {
         public static readonly DerObjectIdentifier SigPolicyId = PkcsObjectIdentifiers.IdAAEtsSigPolicyID;
diff --git a/crypto/src/asn1/esf/OcspIdentifier.cs b/crypto/src/asn1/esf/OcspIdentifier.cs
index fa3d60291..ddf26a7bc 100644
--- a/crypto/src/asn1/esf/OcspIdentifier.cs
+++ b/crypto/src/asn1/esf/OcspIdentifier.cs
@@ -2,52 +2,48 @@ using System;
 
 using Org.BouncyCastle.Asn1.Ocsp;
 using Org.BouncyCastle.Asn1.X509;
-using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Asn1.Esf
 {
-	/// <remarks>
-	/// RFC 3126: 4.2.2 Complete Revocation Refs Attribute Definition
-	/// <code>
-	/// OcspIdentifier ::= SEQUENCE {
-	///		ocspResponderID		ResponderID,
-	///			-- As in OCSP response data
-	///		producedAt			GeneralizedTime
-	///			-- As in OCSP response data
-	/// }
-	/// </code>
-	/// </remarks>
-	public class OcspIdentifier
+    /// <remarks>
+    /// RFC 3126: 4.2.2 Complete Revocation Refs Attribute Definition
+    /// <code>
+    /// OcspIdentifier ::= SEQUENCE {
+    ///		ocspResponderID		ResponderID,
+    ///			-- As in OCSP response data
+    ///		producedAt			GeneralizedTime
+    ///			-- As in OCSP response data
+    /// }
+    /// </code>
+    /// </remarks>
+    public class OcspIdentifier
 		: Asn1Encodable
 	{
-		private readonly ResponderID		ocspResponderID;
-		private readonly Asn1GeneralizedTime producedAt;
-
-		public static OcspIdentifier GetInstance(
-			object obj)
+		public static OcspIdentifier GetInstance(object obj)
 		{
-			if (obj == null || obj is OcspIdentifier)
-				return (OcspIdentifier) obj;
+			if (obj == null)
+				return null;
+			if (obj is OcspIdentifier ocspIdentifier)
+				return ocspIdentifier;
+			return new OcspIdentifier(Asn1Sequence.GetInstance(obj));
+		}
 
-			if (obj is Asn1Sequence)
-				return new OcspIdentifier((Asn1Sequence) obj);
+        public static OcspIdentifier GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new OcspIdentifier(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
 
-			throw new ArgumentException(
-				"Unknown object in 'OcspIdentifier' factory: "
-                    + Platform.GetTypeName(obj),
-				"obj");
-		}
+        private readonly ResponderID m_ocspResponderID;
+        private readonly Asn1GeneralizedTime m_producedAt;
 
-		private OcspIdentifier(
-			Asn1Sequence seq)
+        private OcspIdentifier(Asn1Sequence seq)
 		{
-			if (seq == null)
-				throw new ArgumentNullException("seq");
-			if (seq.Count != 2)
-				throw new ArgumentException("Bad sequence size: " + seq.Count, "seq");
+			int count = 2;
+			if (count != 2)
+				throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
 
-			this.ocspResponderID = ResponderID.GetInstance(seq[0].ToAsn1Object());
-			this.producedAt = (Asn1GeneralizedTime)seq[1].ToAsn1Object();
+			m_ocspResponderID = ResponderID.GetInstance(seq[0]);
+			m_producedAt = Asn1GeneralizedTime.GetInstance(seq[1]);
 		}
 
 		public OcspIdentifier(ResponderID ocspResponderID, DateTime producedAt)
@@ -57,28 +53,16 @@ namespace Org.BouncyCastle.Asn1.Esf
 
         public OcspIdentifier(ResponderID ocspResponderID, Asn1GeneralizedTime producedAt)
         {
-            if (ocspResponderID == null)
-                throw new ArgumentNullException(nameof(ocspResponderID));
-            if (producedAt == null)
-                throw new ArgumentNullException(nameof(producedAt));
-
-            this.ocspResponderID = ocspResponderID;
-            this.producedAt = producedAt;
+            m_ocspResponderID = ocspResponderID ?? throw new ArgumentNullException(nameof(ocspResponderID));
+            m_producedAt = producedAt ?? throw new ArgumentNullException(nameof(producedAt));
         }
 
-        public ResponderID OcspResponderID
-		{
-			get { return ocspResponderID; }
-		}
+		public ResponderID OcspResponderID => m_ocspResponderID;
 
-		public DateTime ProducedAt
-		{
-			get { return producedAt.ToDateTime(); }
-		}
+		public Asn1GeneralizedTime ProducedAtData => m_producedAt;
 
-		public override Asn1Object ToAsn1Object()
-		{
-			return new DerSequence(ocspResponderID, producedAt);
-		}
+		public DateTime ProducedAt => m_producedAt.ToDateTime();
+
+		public override Asn1Object ToAsn1Object() => new DerSequence(m_ocspResponderID, m_producedAt);
 	}
 }
diff --git a/crypto/src/asn1/esf/OcspListID.cs b/crypto/src/asn1/esf/OcspListID.cs
index 974962571..06eb99fc4 100644
--- a/crypto/src/asn1/esf/OcspListID.cs
+++ b/crypto/src/asn1/esf/OcspListID.cs
@@ -1,57 +1,51 @@
 using System;
 using System.Collections.Generic;
 
-using Org.BouncyCastle.Utilities;
-
 namespace Org.BouncyCastle.Asn1.Esf
 {
-	/// <remarks>
-	/// RFC 3126: 4.2.2 Complete Revocation Refs Attribute Definition
-	/// <code>
-	/// OcspListID ::=  SEQUENCE {
-	///		ocspResponses	SEQUENCE OF OcspResponsesID
-	/// }
-	/// </code>
-	/// </remarks>
-	public class OcspListID
+    /// <remarks>
+    /// RFC 3126: 4.2.2 Complete Revocation Refs Attribute Definition
+    /// <code>
+    /// OcspListID ::=  SEQUENCE {
+    ///		ocspResponses	SEQUENCE OF OcspResponsesID
+    /// }
+    /// </code>
+    /// </remarks>
+    public class OcspListID
 		: Asn1Encodable
 	{
-		private readonly Asn1Sequence m_ocspResponses;
-
-		public static OcspListID GetInstance(object obj)
-		{
-			if (obj == null)
-				return null;
-
-			if (obj is OcspListID ocspListID)
-				return ocspListID;
-
-			if (obj is Asn1Sequence asn1Sequence)
-				return new OcspListID(asn1Sequence);
-
-			throw new ArgumentException("Unknown object in 'OcspListID' factory: " + Platform.GetTypeName(obj),
-				nameof(obj));
-		}
-
-		private OcspListID(Asn1Sequence seq)
+        public static OcspListID GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is OcspListID ocspListID)
+                return ocspListID;
+            return new OcspListID(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static OcspListID GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new OcspListID(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
+
+        private readonly Asn1Sequence m_ocspResponses;
+
+        private OcspListID(Asn1Sequence seq)
 		{
-			if (seq == null)
-				throw new ArgumentNullException(nameof(seq));
-			if (seq.Count != 1)
-				throw new ArgumentException("Bad sequence size: " + seq.Count, nameof(seq));
-
-			m_ocspResponses = (Asn1Sequence)seq[0].ToAsn1Object();
+			int count = seq.Count;
+			if (count != 1)
+				throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
 
-            // Validate
-            m_ocspResponses.MapElements(element => OcspResponsesID.GetInstance(element.ToAsn1Object()));
-		}
+			m_ocspResponses = Asn1Sequence.GetInstance(seq[0]);
+            m_ocspResponses.MapElements(OcspResponsesID.GetInstance); // Validate
+        }
 
-		public OcspListID(params OcspResponsesID[] ocspResponses)
+        public OcspListID(params OcspResponsesID[] ocspResponses)
 		{
 			if (ocspResponses == null)
 				throw new ArgumentNullException(nameof(ocspResponses));
 
-			m_ocspResponses = new DerSequence(ocspResponses);
+			m_ocspResponses = DerSequence.FromElements(ocspResponses);
 		}
 
 		public OcspListID(IEnumerable<OcspResponsesID> ocspResponses)
@@ -59,17 +53,11 @@ namespace Org.BouncyCastle.Asn1.Esf
 			if (ocspResponses == null)
                 throw new ArgumentNullException(nameof(ocspResponses));
 
-            m_ocspResponses = new DerSequence(Asn1EncodableVector.FromEnumerable(ocspResponses));
+            m_ocspResponses = DerSequence.FromVector(Asn1EncodableVector.FromEnumerable(ocspResponses));
 		}
 
-		public OcspResponsesID[] GetOcspResponses()
-		{
-            return m_ocspResponses.MapElements(element => OcspResponsesID.GetInstance(element.ToAsn1Object()));
-		}
+		public OcspResponsesID[] GetOcspResponses() => m_ocspResponses.MapElements(OcspResponsesID.GetInstance);
 
-		public override Asn1Object ToAsn1Object()
-		{
-			return new DerSequence(m_ocspResponses);
-		}
+		public override Asn1Object ToAsn1Object() => new DerSequence(m_ocspResponses);
 	}
 }
diff --git a/crypto/src/asn1/esf/OcspResponsesID.cs b/crypto/src/asn1/esf/OcspResponsesID.cs
index 8718188fc..954125e3c 100644
--- a/crypto/src/asn1/esf/OcspResponsesID.cs
+++ b/crypto/src/asn1/esf/OcspResponsesID.cs
@@ -1,94 +1,71 @@
 using System;
 
-using Org.BouncyCastle.Utilities;
-
 namespace Org.BouncyCastle.Asn1.Esf
 {
-	/// <remarks>
-	/// RFC 3126: 4.2.2 Complete Revocation Refs Attribute Definition
-	/// <code>
-	/// OcspResponsesID ::= SEQUENCE {
-	///		ocspIdentifier	OcspIdentifier,
-	///		ocspRepHash		OtherHash OPTIONAL
-	/// }
-	/// </code>
-	/// </remarks>
-	public class OcspResponsesID
+    /// <remarks>
+    /// RFC 3126: 4.2.2 Complete Revocation Refs Attribute Definition
+    /// <code>
+    /// OcspResponsesID ::= SEQUENCE {
+    ///		ocspIdentifier	OcspIdentifier,
+    ///		ocspRepHash		OtherHash OPTIONAL
+    /// }
+    /// </code>
+    /// </remarks>
+    public class OcspResponsesID
 		: Asn1Encodable
 	{
-		private readonly OcspIdentifier	ocspIdentifier;
-		private readonly OtherHash		ocspRepHash;
-
-		public static OcspResponsesID GetInstance(
-			object obj)
-		{
-			if (obj == null || obj is OcspResponsesID)
-				return (OcspResponsesID) obj;
-
-			if (obj is Asn1Sequence)
-				return new OcspResponsesID((Asn1Sequence) obj);
-
-			throw new ArgumentException(
-				"Unknown object in 'OcspResponsesID' factory: "
-                    + Platform.GetTypeName(obj),
-				"obj");
-		}
-
-		private OcspResponsesID(
-			Asn1Sequence seq)
+        public static OcspResponsesID GetInstance(object obj)
+        {
+			if (obj == null)
+				return null;
+            if (obj is OcspResponsesID ocspResponsesID)
+                return ocspResponsesID;
+            return new OcspResponsesID(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static OcspResponsesID GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new OcspResponsesID(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
+
+        private readonly OcspIdentifier m_ocspIdentifier;
+        private readonly OtherHash m_ocspRepHash;
+
+        private OcspResponsesID(Asn1Sequence seq)
 		{
-			if (seq == null)
-				throw new ArgumentNullException("seq");
-			if (seq.Count < 1 || seq.Count > 2)
-				throw new ArgumentException("Bad sequence size: " + seq.Count, "seq");
+			int count = seq.Count;
+			if (count < 1 || count > 2)
+				throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
 
-			this.ocspIdentifier = OcspIdentifier.GetInstance(seq[0].ToAsn1Object());
+			m_ocspIdentifier = OcspIdentifier.GetInstance(seq[0]);
 
 			if (seq.Count > 1)
 			{
-				this.ocspRepHash = OtherHash.GetInstance(seq[1].ToAsn1Object());
+				m_ocspRepHash = OtherHash.GetInstance(seq[1]);
 			}
 		}
 
-		public OcspResponsesID(
-			OcspIdentifier ocspIdentifier)
-			: this(ocspIdentifier, null)
-		{
-		}
-
-		public OcspResponsesID(
-			OcspIdentifier	ocspIdentifier,
-			OtherHash		ocspRepHash)
-		{
-			if (ocspIdentifier == null)
-				throw new ArgumentNullException("ocspIdentifier");
+        public OcspResponsesID(OcspIdentifier ocspIdentifier)
+            : this(ocspIdentifier, null)
+        {
+        }
 
-			this.ocspIdentifier = ocspIdentifier;
-			this.ocspRepHash = ocspRepHash;
+        public OcspResponsesID(OcspIdentifier ocspIdentifier, OtherHash ocspRepHash)
+        {
+			m_ocspIdentifier = ocspIdentifier ?? throw new ArgumentNullException(nameof(ocspIdentifier));
+            m_ocspRepHash = ocspRepHash;
 		}
 
-		public OcspIdentifier OcspIdentifier
-		{
-			get { return ocspIdentifier; }
-		}
+		public OcspIdentifier OcspIdentifier => m_ocspIdentifier;
 
-		public OtherHash OcspRepHash
-		{
-			get { return ocspRepHash; }
-		}
+		public OtherHash OcspRepHash => m_ocspRepHash;
 
 		public override Asn1Object ToAsn1Object()
 		{
-			Asn1EncodableVector v = new Asn1EncodableVector(
-				ocspIdentifier.ToAsn1Object());
-
-			if (ocspRepHash != null)
-			{
-				v.Add(ocspRepHash.ToAsn1Object());
-			}
-
+            Asn1EncodableVector v = new Asn1EncodableVector(2);
+            v.Add(m_ocspIdentifier);
+            v.AddOptional(m_ocspRepHash);
 			return new DerSequence(v);
 		}
-
 	}
 }
diff --git a/crypto/src/asn1/esf/OtherCertID.cs b/crypto/src/asn1/esf/OtherCertID.cs
index 19d173aa2..85c0a646c 100644
--- a/crypto/src/asn1/esf/OtherCertID.cs
+++ b/crypto/src/asn1/esf/OtherCertID.cs
@@ -1,7 +1,6 @@
 using System;
 
 using Org.BouncyCastle.Asn1.X509;
-using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Asn1.Esf
 {
@@ -16,79 +15,58 @@ namespace Org.BouncyCastle.Asn1.Esf
 	public class OtherCertID
 		: Asn1Encodable
 	{
-		private readonly OtherHash		otherCertHash;
-		private readonly IssuerSerial	issuerSerial;
+        public static OtherCertID GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is OtherCertID otherCertID)
+                return otherCertID;
+            return new OtherCertID(Asn1Sequence.GetInstance(obj));
+		}
 
-		public static OtherCertID GetInstance(
-			object obj)
+        public static OtherCertID GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
 		{
-			if (obj == null || obj is OtherCertID)
-				return (OtherCertID) obj;
-
-			if (obj is Asn1Sequence)
-				return new OtherCertID((Asn1Sequence) obj);
-
-			throw new ArgumentException(
-				"Unknown object in 'OtherCertID' factory: "
-                    + Platform.GetTypeName(obj),
-				"obj");
+			return new OtherCertID(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
 		}
 
-		private OtherCertID(
-			Asn1Sequence seq)
+        private readonly OtherHash m_otherCertHash;
+        private readonly IssuerSerial m_issuerSerial;
+
+        private OtherCertID(Asn1Sequence seq)
 		{
-			if (seq == null)
-				throw new ArgumentNullException("seq");
-			if (seq.Count < 1 || seq.Count > 2)
-				throw new ArgumentException("Bad sequence size: " + seq.Count, "seq");
+			int count = seq.Count;
+            if (count < 1 || count > 2)
+                throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
 
-			this.otherCertHash = OtherHash.GetInstance(seq[0].ToAsn1Object());
+			m_otherCertHash = OtherHash.GetInstance(seq[0]);
 
-			if (seq.Count > 1)
+			if (count > 1)
 			{
-				this.issuerSerial = IssuerSerial.GetInstance(seq[1].ToAsn1Object());
+				m_issuerSerial = IssuerSerial.GetInstance(seq[1]);
 			}
 		}
 
-		public OtherCertID(
-			OtherHash otherCertHash)
-			: this(otherCertHash, null)
-		{
-		}
-
-		public OtherCertID(
-			OtherHash		otherCertHash,
-			IssuerSerial	issuerSerial)
-		{
-			if (otherCertHash == null)
-				throw new ArgumentNullException("otherCertHash");
+        public OtherCertID(OtherHash otherCertHash)
+            : this(otherCertHash, null)
+        {
+        }
 
-			this.otherCertHash = otherCertHash;
-			this.issuerSerial = issuerSerial;
+        public OtherCertID(OtherHash otherCertHash, IssuerSerial issuerSerial)
+        {
+            m_otherCertHash = otherCertHash ?? throw new ArgumentNullException(nameof(otherCertHash));
+			m_issuerSerial = issuerSerial;
 		}
 
-		public OtherHash OtherCertHash
-		{
-			get { return otherCertHash; }
-		}
+		public OtherHash OtherCertHash => m_otherCertHash;
 
-		public IssuerSerial IssuerSerial
-		{
-			get { return issuerSerial; }
-		}
+		public IssuerSerial IssuerSerial => m_issuerSerial;
 
 		public override Asn1Object ToAsn1Object()
 		{
-			Asn1EncodableVector v = new Asn1EncodableVector(
-				otherCertHash.ToAsn1Object());
-
-			if (issuerSerial != null)
-			{
-				v.Add(issuerSerial.ToAsn1Object());
-			}
-
+			Asn1EncodableVector v = new Asn1EncodableVector(2);
+			v.Add(m_otherCertHash);
+			v.AddOptional(m_issuerSerial);
 			return new DerSequence(v);
 		}
-
 	}
 }
diff --git a/crypto/src/asn1/esf/OtherHash.cs b/crypto/src/asn1/esf/OtherHash.cs
index 2ee162478..0d8888234 100644
--- a/crypto/src/asn1/esf/OtherHash.cs
+++ b/crypto/src/asn1/esf/OtherHash.cs
@@ -5,84 +5,61 @@ using Org.BouncyCastle.Asn1.X509;
 
 namespace Org.BouncyCastle.Asn1.Esf
 {
-	/// <remarks>
-	/// <code>
-	/// OtherHash ::= CHOICE {
-	///		sha1Hash	OtherHashValue, -- This contains a SHA-1 hash
-	/// 	otherHash	OtherHashAlgAndValue
-	///	}
-	///	
-	///	OtherHashValue ::= OCTET STRING
-	/// </code>
-	/// </remarks>
-	public class OtherHash
+    /// <remarks>
+    /// <code>
+    /// OtherHash ::= CHOICE {
+    ///		sha1Hash	OtherHashValue, -- This contains a SHA-1 hash
+    /// 	otherHash	OtherHashAlgAndValue
+    ///	}
+    ///	
+    ///	OtherHashValue ::= OCTET STRING
+    /// </code>
+    /// </remarks>
+    public class OtherHash
 		: Asn1Encodable, IAsn1Choice
 	{
-		private readonly Asn1OctetString		sha1Hash;
-		private readonly OtherHashAlgAndValue	otherHash;
+        public static OtherHash GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is OtherHash otherHash)
+                return otherHash;
+            if (obj is Asn1OctetString asn1OctetString)
+                return new OtherHash(asn1OctetString);
+            return new OtherHash(OtherHashAlgAndValue.GetInstance(obj));
+        }
 
-		public static OtherHash GetInstance(
-			object obj)
-		{
-			if (obj == null || obj is OtherHash)
-				return (OtherHash) obj;
-
-			if (obj is Asn1OctetString)
-				return new OtherHash((Asn1OctetString) obj);
+        public static OtherHash GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return Asn1Utilities.GetInstanceFromChoice(taggedObject, declaredExplicit, GetInstance);
+        }
 
-			return new OtherHash(
-				OtherHashAlgAndValue.GetInstance(obj));
-		}
+        private readonly Asn1OctetString m_sha1Hash;
+        private readonly OtherHashAlgAndValue m_otherHash;
 
-		public OtherHash(
-			byte[] sha1Hash)
+        public OtherHash(byte[] sha1Hash)
 		{
 			if (sha1Hash == null)
-				throw new ArgumentNullException("sha1Hash");
+				throw new ArgumentNullException(nameof(sha1Hash));
 
-			this.sha1Hash = new DerOctetString(sha1Hash);
+			m_sha1Hash = new DerOctetString(sha1Hash);
 		}
 
-		public OtherHash(
-			Asn1OctetString sha1Hash)
+		public OtherHash(Asn1OctetString sha1Hash)
 		{
-			if (sha1Hash == null)
-				throw new ArgumentNullException("sha1Hash");
-
-			this.sha1Hash = sha1Hash;
+			m_sha1Hash = sha1Hash ?? throw new ArgumentNullException(nameof(sha1Hash));
 		}
 
-		public OtherHash(
-			OtherHashAlgAndValue otherHash)
+		public OtherHash(OtherHashAlgAndValue otherHash)
 		{
-			if (otherHash == null)
-				throw new ArgumentNullException("otherHash");
+			m_otherHash = otherHash ?? throw new ArgumentNullException(nameof(otherHash));
+        }
 
-			this.otherHash = otherHash;
-		}
+		public AlgorithmIdentifier HashAlgorithm =>
+			m_otherHash?.HashAlgorithm ?? new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1);
 
-		public AlgorithmIdentifier HashAlgorithm
-		{
-			get
-			{
-				return otherHash == null
-					?	new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1)
-					:	otherHash.HashAlgorithm;
-			}
-		}
-
-		public byte[] GetHashValue()
-		{
-			return otherHash == null
-				?	sha1Hash.GetOctets()
-				:	otherHash.GetHashValue();
-		}
+		public byte[] GetHashValue() => m_otherHash?.GetHashValue() ?? m_sha1Hash.GetOctets();
 
-		public override Asn1Object ToAsn1Object()
-		{
-			return otherHash == null
-				?	sha1Hash
-				:	otherHash.ToAsn1Object();
-		}
+		public override Asn1Object ToAsn1Object() => m_otherHash?.ToAsn1Object() ?? m_sha1Hash;
 	}
 }
diff --git a/crypto/src/asn1/esf/OtherHashAlgAndValue.cs b/crypto/src/asn1/esf/OtherHashAlgAndValue.cs
index 00eb24c54..a99888a84 100644
--- a/crypto/src/asn1/esf/OtherHashAlgAndValue.cs
+++ b/crypto/src/asn1/esf/OtherHashAlgAndValue.cs
@@ -1,95 +1,73 @@
 using System;
 
 using Org.BouncyCastle.Asn1.X509;
-using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Asn1.Esf
 {
-	/// <summary>
-	/// Summary description for OtherHashAlgAndValue.
-	/// </summary>
-	/// <remarks>
-	/// <code>
-	/// OtherHashAlgAndValue ::= SEQUENCE {
-	///		hashAlgorithm	AlgorithmIdentifier,
-	/// 	hashValue		OtherHashValue
-	/// }
-	/// 
-	/// OtherHashValue ::= OCTET STRING
-	/// </code>
-	/// </remarks>
-	public class OtherHashAlgAndValue
+    /// <summary>
+    /// Summary description for OtherHashAlgAndValue.
+    /// </summary>
+    /// <remarks>
+    /// <code>
+    /// OtherHashAlgAndValue ::= SEQUENCE {
+    ///		hashAlgorithm	AlgorithmIdentifier,
+    /// 	hashValue		OtherHashValue
+    /// }
+    /// 
+    /// OtherHashValue ::= OCTET STRING
+    /// </code>
+    /// </remarks>
+    public class OtherHashAlgAndValue
 		: Asn1Encodable
 	{
-		private readonly AlgorithmIdentifier	hashAlgorithm;
-		private readonly Asn1OctetString		hashValue;
+        public static OtherHashAlgAndValue GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is OtherHashAlgAndValue otherHashAlgAndValue)
+                return otherHashAlgAndValue;
+            return new OtherHashAlgAndValue(Asn1Sequence.GetInstance(obj));
+        }
 
-		public static OtherHashAlgAndValue GetInstance(
-			object obj)
-		{
-			if (obj == null || obj is OtherHashAlgAndValue)
-				return (OtherHashAlgAndValue) obj;
-
-			if (obj is Asn1Sequence)
-				return new OtherHashAlgAndValue((Asn1Sequence) obj);
+        public static OtherHashAlgAndValue GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new OtherHashAlgAndValue(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
 
-			throw new ArgumentException(
-				"Unknown object in 'OtherHashAlgAndValue' factory: "
-                    + Platform.GetTypeName(obj),
-				"obj");
-		}
+        private readonly AlgorithmIdentifier m_hashAlgorithm;
+        private readonly Asn1OctetString m_hashValue;
 
-		private OtherHashAlgAndValue(
-			Asn1Sequence seq)
+        private OtherHashAlgAndValue(Asn1Sequence seq)
 		{
-			if (seq == null)
-				throw new ArgumentNullException("seq");
-			if (seq.Count != 2)
-				throw new ArgumentException("Bad sequence size: " + seq.Count, "seq");
+			int count = seq.Count;
+			if (count != 2)
+				throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
 
-			this.hashAlgorithm = AlgorithmIdentifier.GetInstance(seq[0].ToAsn1Object());
-			this.hashValue = (Asn1OctetString) seq[1].ToAsn1Object();
+			m_hashAlgorithm = AlgorithmIdentifier.GetInstance(seq[0]);
+			m_hashValue = Asn1OctetString.GetInstance(seq[1]);
 		}
 
-		public OtherHashAlgAndValue(
-			AlgorithmIdentifier	hashAlgorithm,
-			byte[]				hashValue)
+		public OtherHashAlgAndValue(AlgorithmIdentifier	hashAlgorithm, byte[] hashValue)
 		{
 			if (hashAlgorithm == null)
-				throw new ArgumentNullException("hashAlgorithm");
+				throw new ArgumentNullException(nameof(hashAlgorithm));
 			if (hashValue == null)
-				throw new ArgumentNullException("hashValue");
+				throw new ArgumentNullException(nameof(hashValue));
 
-			this.hashAlgorithm = hashAlgorithm;
-			this.hashValue = new DerOctetString(hashValue);
+			m_hashAlgorithm = hashAlgorithm;
+			m_hashValue = new DerOctetString(hashValue);
 		}
 
-		public OtherHashAlgAndValue(
-			AlgorithmIdentifier	hashAlgorithm,
-			Asn1OctetString		hashValue)
-		{
-			if (hashAlgorithm == null)
-				throw new ArgumentNullException("hashAlgorithm");
-			if (hashValue == null)
-				throw new ArgumentNullException("hashValue");
-
-			this.hashAlgorithm = hashAlgorithm;
-			this.hashValue = hashValue;
+        public OtherHashAlgAndValue(AlgorithmIdentifier hashAlgorithm, Asn1OctetString hashValue)
+        {
+			m_hashAlgorithm = hashAlgorithm ?? throw new ArgumentNullException(nameof(hashAlgorithm));
+            m_hashValue = hashValue ?? throw new ArgumentNullException(nameof(hashValue));
 		}
 
-		public AlgorithmIdentifier HashAlgorithm
-		{
-			get { return hashAlgorithm; }
-		}
+		public AlgorithmIdentifier HashAlgorithm => m_hashAlgorithm;
 
-		public byte[] GetHashValue()
-		{
-			return hashValue.GetOctets();
-		}
+		public byte[] GetHashValue() => m_hashValue.GetOctets();
 
-		public override Asn1Object ToAsn1Object()
-		{
-			return new DerSequence(hashAlgorithm, hashValue);
-		}
+		public override Asn1Object ToAsn1Object() => new DerSequence(m_hashAlgorithm, m_hashValue);
 	}
 }
diff --git a/crypto/src/asn1/esf/OtherRevRefs.cs b/crypto/src/asn1/esf/OtherRevRefs.cs
index 446031e5a..3aeade98c 100644
--- a/crypto/src/asn1/esf/OtherRevRefs.cs
+++ b/crypto/src/asn1/esf/OtherRevRefs.cs
@@ -1,80 +1,62 @@
 using System;
 
-using Org.BouncyCastle.Utilities;
-
 namespace Org.BouncyCastle.Asn1.Esf
 {
-	/// <remarks>
-	/// RFC 3126: 4.2.2 Complete Revocation Refs Attribute Definition
-	/// <code>
-	/// OtherRevRefs ::= SEQUENCE 
-	/// {
-	///		otherRevRefType      OtherRevRefType,
-	///		otherRevRefs         ANY DEFINED BY otherRevRefType
-	/// }
-	///
-	/// OtherRevRefType ::= OBJECT IDENTIFIER
-	/// </code>
-	/// </remarks>
-	public class OtherRevRefs
+    /// <remarks>
+    /// RFC 3126: 4.2.2 Complete Revocation Refs Attribute Definition
+    /// <code>
+    /// OtherRevRefs ::= SEQUENCE 
+    /// {
+    ///		otherRevRefType      OtherRevRefType,
+    ///		otherRevRefs         ANY DEFINED BY otherRevRefType
+    /// }
+    ///
+    /// OtherRevRefType ::= OBJECT IDENTIFIER
+    /// </code>
+    /// </remarks>
+    public class OtherRevRefs
 		: Asn1Encodable
 	{
-		private readonly DerObjectIdentifier	otherRevRefType;
-		private readonly Asn1Object				otherRevRefs;
-
-		public static OtherRevRefs GetInstance(
-			object obj)
+		public static OtherRevRefs GetInstance(object obj)
 		{
-			if (obj == null || obj is OtherRevRefs)
-				return (OtherRevRefs) obj;
+			if (obj == null)
+				return null;
+			if (obj is OtherRevRefs otherRevRefs)
+				return otherRevRefs;
+			return new OtherRevRefs(Asn1Sequence.GetInstance(obj));
+		}
 
-			if (obj is Asn1Sequence)
-				return new OtherRevRefs((Asn1Sequence) obj);
+        public static OtherRevRefs GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new OtherRevRefs(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
 
-			throw new ArgumentException(
-				"Unknown object in 'OtherRevRefs' factory: "
-                    + Platform.GetTypeName(obj),
-				"obj");
-		}
+        private readonly DerObjectIdentifier m_otherRevRefType;
+        private readonly Asn1Encodable m_otherRevRefs;
 
-		private OtherRevRefs(
-			Asn1Sequence seq)
+        private OtherRevRefs(Asn1Sequence seq)
 		{
-			if (seq == null)
-				throw new ArgumentNullException("seq");
-			if (seq.Count != 2)
-				throw new ArgumentException("Bad sequence size: " + seq.Count, "seq");
+            int count = seq.Count;
+            if (count != 2)
+                throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
 
-			this.otherRevRefType = (DerObjectIdentifier) seq[0].ToAsn1Object();
-			this.otherRevRefs = seq[1].ToAsn1Object();
+			m_otherRevRefType = DerObjectIdentifier.GetInstance(seq[0]);
+			m_otherRevRefs = seq[1];
 		}
 
-		public OtherRevRefs(
-			DerObjectIdentifier	otherRevRefType,
-			Asn1Encodable		otherRevRefs)
-		{
-			if (otherRevRefType == null)
-				throw new ArgumentNullException("otherRevRefType");
-			if (otherRevRefs == null)
-				throw new ArgumentNullException("otherRevRefs");
+        public OtherRevRefs(DerObjectIdentifier otherRevRefType, Asn1Encodable otherRevRefs)
+        {
+			m_otherRevRefType = otherRevRefType ?? throw new ArgumentNullException(nameof(otherRevRefType));
+            m_otherRevRefs = otherRevRefs ?? throw new ArgumentNullException(nameof(otherRevRefs));
+        }
 
-			this.otherRevRefType = otherRevRefType;
-			this.otherRevRefs = otherRevRefs.ToAsn1Object();
-		}
+        public DerObjectIdentifier OtherRevRefType => m_otherRevRefType;
 
-		public DerObjectIdentifier OtherRevRefType
-		{
-			get { return otherRevRefType; }
-		}
+		public Asn1Encodable OtherRevRefsData => m_otherRevRefs;
 
-		public Asn1Object OtherRevRefsObject
-		{
-			get { return otherRevRefs; }
-		}
+		[Obsolete("Use 'OtherRevRefsData' instead")]
+		public Asn1Object OtherRevRefsObject => m_otherRevRefs.ToAsn1Object();
 
-		public override Asn1Object ToAsn1Object()
-		{
-			return new DerSequence(otherRevRefType, otherRevRefs);
-		}
+		public override Asn1Object ToAsn1Object() => new DerSequence(m_otherRevRefType, m_otherRevRefs);
 	}
 }
diff --git a/crypto/src/asn1/esf/OtherRevVals.cs b/crypto/src/asn1/esf/OtherRevVals.cs
index 7b904565a..6459f0657 100644
--- a/crypto/src/asn1/esf/OtherRevVals.cs
+++ b/crypto/src/asn1/esf/OtherRevVals.cs
@@ -1,80 +1,62 @@
 using System;
 
-using Org.BouncyCastle.Utilities;
-
 namespace Org.BouncyCastle.Asn1.Esf
 {
-	/// <remarks>
-	/// RFC 3126: 4.3.2 Revocation Values Attribute Definition
-	/// <code>
-	/// OtherRevVals ::= SEQUENCE 
-	/// {
-	///		otherRevValType      OtherRevValType,
-	///		otherRevVals         ANY DEFINED BY otherRevValType
-	/// }
-	///
-	/// OtherRevValType ::= OBJECT IDENTIFIER
-	/// </code>
-	/// </remarks>
-	public class OtherRevVals
+    /// <remarks>
+    /// RFC 3126: 4.3.2 Revocation Values Attribute Definition
+    /// <code>
+    /// OtherRevVals ::= SEQUENCE 
+    /// {
+    ///		otherRevValType      OtherRevValType,
+    ///		otherRevVals         ANY DEFINED BY otherRevValType
+    /// }
+    ///
+    /// OtherRevValType ::= OBJECT IDENTIFIER
+    /// </code>
+    /// </remarks>
+    public class OtherRevVals
 		: Asn1Encodable
 	{
-		private readonly DerObjectIdentifier	otherRevValType;
-		private readonly Asn1Object				otherRevVals;
-
-		public static OtherRevVals GetInstance(
-			object obj)
+        public static OtherRevVals GetInstance(object obj)
+        {
+			if (obj == null)
+				return null;
+            if (obj is OtherRevVals otherRevVals)
+                return otherRevVals;
+            return new OtherRevVals(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static OtherRevVals GetInstance(Asn1TaggedObject obj, bool explicitly)
+        {
+            return new OtherRevVals(Asn1Sequence.GetInstance(obj, explicitly));
+        }
+
+        private readonly DerObjectIdentifier m_otherRevValType;
+        private readonly Asn1Encodable m_otherRevVals;
+
+        private OtherRevVals(Asn1Sequence seq)
 		{
-			if (obj == null || obj is OtherRevVals)
-				return (OtherRevVals) obj;
+			int count = seq.Count;
+			if (count != 2)
+				throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
 
-			if (obj is Asn1Sequence)
-				return new OtherRevVals((Asn1Sequence) obj);
-
-			throw new ArgumentException(
-				"Unknown object in 'OtherRevVals' factory: "
-                    + Platform.GetTypeName(obj),
-				"obj");
+			m_otherRevValType = DerObjectIdentifier.GetInstance(seq[0]);
+			m_otherRevVals = seq[1];
 		}
 
-		private OtherRevVals(
-			Asn1Sequence seq)
-		{
-			if (seq == null)
-				throw new ArgumentNullException("seq");
-			if (seq.Count != 2)
-				throw new ArgumentException("Bad sequence size: " + seq.Count, "seq");
+        public OtherRevVals(DerObjectIdentifier otherRevValType, Asn1Encodable otherRevVals)
+        {
+            m_otherRevValType = otherRevValType ?? throw new ArgumentNullException(nameof(otherRevValType));
+            m_otherRevVals = otherRevVals ?? throw new ArgumentNullException(nameof(otherRevVals));
+        }
 
-			this.otherRevValType = (DerObjectIdentifier) seq[0].ToAsn1Object();
-			this.otherRevVals = seq[1].ToAsn1Object();
-		}
+		public DerObjectIdentifier OtherRevValType => m_otherRevValType;
 
-		public OtherRevVals(
-			DerObjectIdentifier	otherRevValType,
-			Asn1Encodable		otherRevVals)
-		{
-			if (otherRevValType == null)
-				throw new ArgumentNullException("otherRevValType");
-			if (otherRevVals == null)
-				throw new ArgumentNullException("otherRevVals");
+		public Asn1Encodable OtherRevValsData => m_otherRevVals;
 
-			this.otherRevValType = otherRevValType;
-			this.otherRevVals = otherRevVals.ToAsn1Object();
-		}
+        [Obsolete("Use 'OtherRevValsData' instead")]
+        public Asn1Object OtherRevValsObject => m_otherRevVals.ToAsn1Object();
 
-		public DerObjectIdentifier OtherRevValType
-		{
-			get { return otherRevValType; }
-		}
-
-		public Asn1Object OtherRevValsObject
-		{
-			get { return otherRevVals; }
-		}
-
-		public override Asn1Object ToAsn1Object()
-		{
-			return new DerSequence(otherRevValType, otherRevVals);
-		}
+		public override Asn1Object ToAsn1Object() => new DerSequence(m_otherRevValType, m_otherRevVals);
 	}
 }
diff --git a/crypto/src/asn1/esf/OtherSigningCertificate.cs b/crypto/src/asn1/esf/OtherSigningCertificate.cs
index aa1dcbf99..78fda76d1 100644
--- a/crypto/src/asn1/esf/OtherSigningCertificate.cs
+++ b/crypto/src/asn1/esf/OtherSigningCertificate.cs
@@ -2,51 +2,48 @@ using System;
 using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1.X509;
-using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Asn1.Esf
 {
-	/// <remarks>
-	/// <code>
-	/// OtherSigningCertificate ::= SEQUENCE {
-	/// 	certs		SEQUENCE OF OtherCertID,
-	/// 	policies	SEQUENCE OF PolicyInformation OPTIONAL
-	/// }
-	/// </code>
-	/// </remarks>
-	public class OtherSigningCertificate
+    /// <remarks>
+    /// <code>
+    /// OtherSigningCertificate ::= SEQUENCE {
+    /// 	certs		SEQUENCE OF OtherCertID,
+    /// 	policies	SEQUENCE OF PolicyInformation OPTIONAL
+    /// }
+    /// </code>
+    /// </remarks>
+    public class OtherSigningCertificate
 		: Asn1Encodable
 	{
-		private readonly Asn1Sequence m_certs;
-		private readonly Asn1Sequence m_policies;
-
 		public static OtherSigningCertificate GetInstance(object obj)
 		{
 			if (obj == null)
 				return null;
-
 			if (obj is OtherSigningCertificate otherSigningCertificate)
 				return otherSigningCertificate;
+			return new OtherSigningCertificate(Asn1Sequence.GetInstance(obj));
+		}
 
-			if (obj is Asn1Sequence asn1Sequence)
-				return new OtherSigningCertificate(asn1Sequence);
+        public static OtherSigningCertificate GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new OtherSigningCertificate(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
 
-			throw new ArgumentException("Unknown object in 'OtherSigningCertificate' factory: " + Platform.GetTypeName(obj),
-				nameof(obj));
-		}
+        private readonly Asn1Sequence m_certs;
+        private readonly Asn1Sequence m_policies;
 
-		private OtherSigningCertificate(Asn1Sequence seq)
+        private OtherSigningCertificate(Asn1Sequence seq)
 		{
-			if (seq == null)
-				throw new ArgumentNullException(nameof(seq));
-			if (seq.Count < 1 || seq.Count > 2)
-				throw new ArgumentException("Bad sequence size: " + seq.Count, nameof(seq));
+			int count = seq.Count;
+			if (count < 1 || count > 2)
+				throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
 
-			m_certs = Asn1Sequence.GetInstance(seq[0].ToAsn1Object());
+			m_certs = Asn1Sequence.GetInstance(seq[0]);
 
-			if (seq.Count > 1)
+			if (count > 1)
 			{
-				m_policies = Asn1Sequence.GetInstance(seq[1].ToAsn1Object());
+				m_policies = Asn1Sequence.GetInstance(seq[1]);
 			}
 		}
 
@@ -60,11 +57,11 @@ namespace Org.BouncyCastle.Asn1.Esf
 			if (certs == null)
                 throw new ArgumentNullException(nameof(certs));
 
-            m_certs = new DerSequence(certs);
+            m_certs = DerSequence.FromElements(certs);
 
 			if (policies != null)
 			{
-				m_policies = new DerSequence(policies);
+				m_policies = DerSequence.FromElements(policies);
 			}
 		}
 
@@ -78,27 +75,22 @@ namespace Org.BouncyCastle.Asn1.Esf
 			if (certs == null)
                 throw new ArgumentNullException(nameof(certs));
 
-            m_certs = new DerSequence(Asn1EncodableVector.FromEnumerable(certs));
+            m_certs = DerSequence.FromVector(Asn1EncodableVector.FromEnumerable(certs));
 
 			if (policies != null)
 			{
-				m_policies = new DerSequence(Asn1EncodableVector.FromEnumerable(policies));
+				m_policies = DerSequence.FromVector(Asn1EncodableVector.FromEnumerable(policies));
 			}
 		}
 
-		public OtherCertID[] GetCerts()
-		{
-			return m_certs.MapElements(element => OtherCertID.GetInstance(element.ToAsn1Object()));
-		}
+		public OtherCertID[] GetCerts() => m_certs.MapElements(OtherCertID.GetInstance);
 
-		public PolicyInformation[] GetPolicies()
-		{
-            return m_policies?.MapElements(element => PolicyInformation.GetInstance(element.ToAsn1Object()));
-		}
+		public PolicyInformation[] GetPolicies() => m_policies?.MapElements(PolicyInformation.GetInstance);
 
 		public override Asn1Object ToAsn1Object()
 		{
-			Asn1EncodableVector v = new Asn1EncodableVector(m_certs);
+			Asn1EncodableVector v = new Asn1EncodableVector(2);
+			v.Add(m_certs);
             v.AddOptional(m_policies);
 			return new DerSequence(v);
 		}
diff --git a/crypto/src/asn1/esf/RevocationValues.cs b/crypto/src/asn1/esf/RevocationValues.cs
index 497bf15f2..eef246ee8 100644
--- a/crypto/src/asn1/esf/RevocationValues.cs
+++ b/crypto/src/asn1/esf/RevocationValues.cs
@@ -6,81 +6,67 @@ using Org.BouncyCastle.Asn1.X509;
 
 namespace Org.BouncyCastle.Asn1.Esf
 {
-	/// <remarks>
-	/// RFC 5126: 6.3.4.  revocation-values Attribute Definition
-	/// <code>
-	/// RevocationValues ::=  SEQUENCE {
-	///		crlVals			[0] SEQUENCE OF CertificateList     OPTIONAL,
-	///		ocspVals		[1] SEQUENCE OF BasicOCSPResponse   OPTIONAL,
-	///		otherRevVals	[2] OtherRevVals OPTIONAL
-	/// }
-	/// </code>
-	/// </remarks>
-	public class RevocationValues
+    /// <remarks>
+    /// RFC 5126: 6.3.4.  revocation-values Attribute Definition
+    /// <code>
+    /// RevocationValues ::=  SEQUENCE {
+    ///		crlVals			[0] SEQUENCE OF CertificateList     OPTIONAL,
+    ///		ocspVals		[1] SEQUENCE OF BasicOCSPResponse   OPTIONAL,
+    ///		otherRevVals	[2] OtherRevVals OPTIONAL
+    /// }
+    /// </code>
+    /// </remarks>
+    public class RevocationValues
 		: Asn1Encodable
 	{
-		private readonly Asn1Sequence m_crlVals;
-		private readonly Asn1Sequence m_ocspVals;
-		private readonly OtherRevVals m_otherRevVals;
-
 		public static RevocationValues GetInstance(object obj)
 		{
             if (obj == null)
                 return null;
-
             if (obj is RevocationValues revocationValues)
 				return revocationValues;
-
 			return new RevocationValues(Asn1Sequence.GetInstance(obj));
 		}
 
-		private RevocationValues(Asn1Sequence seq)
+        public static RevocationValues GetInstance(Asn1TaggedObject obj, bool explicitly)
+        {
+            return new RevocationValues(Asn1Sequence.GetInstance(obj, explicitly));
+        }
+
+        private readonly Asn1Sequence m_crlVals;
+        private readonly Asn1Sequence m_ocspVals;
+        private readonly OtherRevVals m_otherRevVals;
+
+        private RevocationValues(Asn1Sequence seq)
 		{
-			if (seq == null)
-				throw new ArgumentNullException(nameof(seq));
-			if (seq.Count > 3)
-				throw new ArgumentException("Bad sequence size: " + seq.Count, nameof(seq));
+			int count = seq.Count;
+			if (count < 0 || count > 3)
+				throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
 
-			foreach (var element in seq)
-			{
-				var o = Asn1TaggedObject.GetInstance(element, Asn1Tags.ContextSpecific);
-				switch (o.TagNo)
-				{
-				case 0:
-					Asn1Sequence crlValsSeq = (Asn1Sequence)o.GetExplicitBaseObject();
-
-					// Validate
-					crlValsSeq.MapElements(CertificateList.GetInstance);
-
-					m_crlVals = crlValsSeq;
-					break;
-				case 1:
-					Asn1Sequence ocspValsSeq = (Asn1Sequence)o.GetExplicitBaseObject();
-
-					// Validate
-					ocspValsSeq.MapElements(BasicOcspResponse.GetInstance);
-
-					m_ocspVals = ocspValsSeq;
-					break;
-				case 2:
-					m_otherRevVals = OtherRevVals.GetInstance(o.GetExplicitBaseObject());
-					break;
-				default:
-					throw new ArgumentException("Illegal tag in RevocationValues", nameof(seq));
-				}
-			}
-		}
+			int pos = 0;
+
+			m_crlVals = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 0, true, Asn1Sequence.GetInstance);
+            m_crlVals?.MapElements(CertificateList.GetInstance); // Validate
+
+            m_ocspVals = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 1, true, Asn1Sequence.GetInstance);
+            m_ocspVals?.MapElements(BasicOcspResponse.GetInstance); // Validate
+
+            m_otherRevVals = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 2, true, OtherRevVals.GetInstance);
 
-		public RevocationValues(CertificateList[] crlVals, BasicOcspResponse[] ocspVals, OtherRevVals otherRevVals)
+            if (pos != count)
+                throw new ArgumentException("Unexpected elements in sequence", nameof(seq));
+        }
+
+        public RevocationValues(CertificateList[] crlVals, BasicOcspResponse[] ocspVals, OtherRevVals otherRevVals)
 		{
 			if (crlVals != null)
 			{
-				m_crlVals = new DerSequence(crlVals);
+				m_crlVals = DerSequence.FromElements(crlVals);
 			}
 
 			if (ocspVals != null)
 			{
-				m_ocspVals = new DerSequence(ocspVals);
+				m_ocspVals = DerSequence.FromElements(ocspVals);
 			}
 
 			m_otherRevVals = otherRevVals;
@@ -91,44 +77,30 @@ namespace Org.BouncyCastle.Asn1.Esf
 		{
 			if (crlVals != null)
 			{
-				m_crlVals = new DerSequence(Asn1EncodableVector.FromEnumerable(crlVals));
+				m_crlVals = DerSequence.FromVector(Asn1EncodableVector.FromEnumerable(crlVals));
 			}
 
 			if (ocspVals != null)
 			{
-				m_ocspVals = new DerSequence(Asn1EncodableVector.FromEnumerable(ocspVals));
+				m_ocspVals = DerSequence.FromVector(Asn1EncodableVector.FromEnumerable(ocspVals));
 			}
 
 			m_otherRevVals = otherRevVals;
 		}
 
-		public CertificateList[] GetCrlVals()
-		{
-			return m_crlVals.MapElements(element => CertificateList.GetInstance(element.ToAsn1Object()));
-		}
+		public CertificateList[] GetCrlVals() => m_crlVals?.MapElements(CertificateList.GetInstance);
 
-		public BasicOcspResponse[] GetOcspVals()
-		{
-            return m_ocspVals.MapElements(element => BasicOcspResponse.GetInstance(element.ToAsn1Object()));
-		}
+		public BasicOcspResponse[] GetOcspVals() => m_ocspVals?.MapElements(BasicOcspResponse.GetInstance);
 
-		public OtherRevVals OtherRevVals
-		{
-			get { return m_otherRevVals; }
-		}
+		public OtherRevVals OtherRevVals => m_otherRevVals;
 
 		public override Asn1Object ToAsn1Object()
 		{
 			Asn1EncodableVector v = new Asn1EncodableVector(3);
             v.AddOptionalTagged(true, 0, m_crlVals);
             v.AddOptionalTagged(true, 1, m_ocspVals);
-
-            if (m_otherRevVals != null)
-			{
-				v.Add(new DerTaggedObject(true, 2, m_otherRevVals.ToAsn1Object()));
-			}
-
-            return new DerSequence(v);
+            v.AddOptionalTagged(true, 2, m_otherRevVals);
+            return DerSequence.FromVector(v);
 		}
 	}
 }
diff --git a/crypto/src/asn1/esf/SigPolicyQualifierInfo.cs b/crypto/src/asn1/esf/SigPolicyQualifierInfo.cs
index 470c5c873..b39b02154 100644
--- a/crypto/src/asn1/esf/SigPolicyQualifierInfo.cs
+++ b/crypto/src/asn1/esf/SigPolicyQualifierInfo.cs
@@ -17,57 +17,46 @@ namespace Org.BouncyCastle.Asn1.Esf
 	public class SigPolicyQualifierInfo
 		: Asn1Encodable
 	{
-		private readonly DerObjectIdentifier	sigPolicyQualifierId;
-		private readonly Asn1Object				sigQualifier;
-
-		public static SigPolicyQualifierInfo GetInstance(
-			object obj)
+        public static SigPolicyQualifierInfo GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is SigPolicyQualifierInfo sigPolicyQualifierInfo)
+                return sigPolicyQualifierInfo;
+            return new SigPolicyQualifierInfo(Asn1Sequence.GetInstance(obj));
+        }
+
+        public static SigPolicyQualifierInfo GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new SigPolicyQualifierInfo(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
+
+        private readonly DerObjectIdentifier m_sigPolicyQualifierId;
+        private readonly Asn1Encodable m_sigQualifier;
+
+        private SigPolicyQualifierInfo(Asn1Sequence seq)
 		{
-			if (obj == null || obj is SigPolicyQualifierInfo)
-				return (SigPolicyQualifierInfo) obj;
-
-			if (obj is Asn1Sequence)
-				return new SigPolicyQualifierInfo((Asn1Sequence) obj);
+			int count = seq.Count;
+			if (count != 2)
+				throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
 
-			throw new ArgumentException(
-				"Unknown object in 'SigPolicyQualifierInfo' factory: "
-                    + Platform.GetTypeName(obj),
-				"obj");
+			m_sigPolicyQualifierId = DerObjectIdentifier.GetInstance(seq[0]);
+			m_sigQualifier = seq[1];
 		}
 
-		private SigPolicyQualifierInfo(
-			Asn1Sequence seq)
-		{
-			if (seq == null)
-				throw new ArgumentNullException("seq");
-			if (seq.Count != 2)
-				throw new ArgumentException("Bad sequence size: " + seq.Count, "seq");
-
-			this.sigPolicyQualifierId = (DerObjectIdentifier) seq[0].ToAsn1Object();
-			this.sigQualifier = seq[1].ToAsn1Object();
+        public SigPolicyQualifierInfo(DerObjectIdentifier sigPolicyQualifierId, Asn1Encodable sigQualifier)
+        {
+            m_sigPolicyQualifierId = sigPolicyQualifierId ?? throw new ArgumentNullException(nameof(sigPolicyQualifierId));
+			m_sigQualifier = sigQualifier ?? throw new ArgumentNullException(nameof(sigQualifier));
 		}
 
-		public SigPolicyQualifierInfo(
-			DerObjectIdentifier	sigPolicyQualifierId,
-			Asn1Encodable		sigQualifier)
-		{
-			this.sigPolicyQualifierId = sigPolicyQualifierId;
-			this.sigQualifier = sigQualifier.ToAsn1Object();
-		}
+		public DerObjectIdentifier SigPolicyQualifierId => m_sigPolicyQualifierId;
 
-		public DerObjectIdentifier SigPolicyQualifierId
-		{
-			get { return sigPolicyQualifierId; }
-		}
+        public Asn1Encodable SigQualifierData => m_sigQualifier;
 
-		public Asn1Object SigQualifier
-		{
-			get { return sigQualifier; }
-		}
+		[Obsolete("Use 'SigQualifierData' instead")]
+        public Asn1Object SigQualifier => m_sigQualifier.ToAsn1Object();
 
-		public override Asn1Object ToAsn1Object()
-		{
-			return new DerSequence(sigPolicyQualifierId, sigQualifier);
-		}
+		public override Asn1Object ToAsn1Object() => new DerSequence(m_sigPolicyQualifierId, m_sigQualifier);
 	}
 }
diff --git a/crypto/src/asn1/esf/SignaturePolicyId.cs b/crypto/src/asn1/esf/SignaturePolicyId.cs
index 84e9f8c62..18ea1634a 100644
--- a/crypto/src/asn1/esf/SignaturePolicyId.cs
+++ b/crypto/src/asn1/esf/SignaturePolicyId.cs
@@ -1,58 +1,54 @@
 using System;
 using System.Collections.Generic;
 
-using Org.BouncyCastle.Utilities;
-
 namespace Org.BouncyCastle.Asn1.Esf
 {
-	/// <remarks>
-	/// <code>
-	/// SignaturePolicyId ::= SEQUENCE {
-	/// 	sigPolicyIdentifier		SigPolicyId,
-	/// 	sigPolicyHash			SigPolicyHash,
-	/// 	sigPolicyQualifiers		SEQUENCE SIZE (1..MAX) OF SigPolicyQualifierInfo OPTIONAL
-	/// }
-	/// 
-	/// SigPolicyId ::= OBJECT IDENTIFIER
-	/// 
-	/// SigPolicyHash ::= OtherHashAlgAndValue
-	/// </code>
-	/// </remarks>
-	public class SignaturePolicyId
+    /// <remarks>
+    /// <code>
+    /// SignaturePolicyId ::= SEQUENCE {
+    /// 	sigPolicyIdentifier		SigPolicyId,
+    /// 	sigPolicyHash			SigPolicyHash,
+    /// 	sigPolicyQualifiers		SEQUENCE SIZE (1..MAX) OF SigPolicyQualifierInfo OPTIONAL
+    /// }
+    /// 
+    /// SigPolicyId ::= OBJECT IDENTIFIER
+    /// 
+    /// SigPolicyHash ::= OtherHashAlgAndValue
+    /// </code>
+    /// </remarks>
+    public class SignaturePolicyId
 		: Asn1Encodable
 	{
-		private readonly DerObjectIdentifier m_sigPolicyIdentifier;
-		private readonly OtherHashAlgAndValue m_sigPolicyHash;
-		private readonly Asn1Sequence m_sigPolicyQualifiers;
-
 		public static SignaturePolicyId GetInstance(object obj)
 		{
 			if (obj == null)
 				return null;
-
 			if (obj is SignaturePolicyId signaturePolicyId)
 				return signaturePolicyId;
+			return new SignaturePolicyId(Asn1Sequence.GetInstance(obj));
+		}
 
-			if (obj is Asn1Sequence asn1Sequence)
-				return new SignaturePolicyId(asn1Sequence);
+        public static SignaturePolicyId GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new SignaturePolicyId(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
 
-			throw new ArgumentException("Unknown object in 'SignaturePolicyId' factory: " + Platform.GetTypeName(obj),
-				nameof(obj));
-		}
+        private readonly DerObjectIdentifier m_sigPolicyIdentifier;
+        private readonly OtherHashAlgAndValue m_sigPolicyHash;
+        private readonly Asn1Sequence m_sigPolicyQualifiers;
 
-		private SignaturePolicyId(Asn1Sequence seq)
+        private SignaturePolicyId(Asn1Sequence seq)
 		{
-			if (seq == null)
-				throw new ArgumentNullException(nameof(seq));
-			if (seq.Count < 2 || seq.Count > 3)
-				throw new ArgumentException("Bad sequence size: " + seq.Count, nameof(seq));
+			int count = seq.Count;
+			if (count < 2 || count > 3)
+				throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
 
-			m_sigPolicyIdentifier = (DerObjectIdentifier)seq[0].ToAsn1Object();
-			m_sigPolicyHash = OtherHashAlgAndValue.GetInstance(seq[1].ToAsn1Object());
+			m_sigPolicyIdentifier = DerObjectIdentifier.GetInstance(seq[0]);
+			m_sigPolicyHash = OtherHashAlgAndValue.GetInstance(seq[1]);
 
-			if (seq.Count > 2)
+			if (count > 2)
 			{
-				m_sigPolicyQualifiers = (Asn1Sequence)seq[2].ToAsn1Object();
+				m_sigPolicyQualifiers = Asn1Sequence.GetInstance(seq[2]);
 			}
 		}
 
@@ -64,62 +60,39 @@ namespace Org.BouncyCastle.Asn1.Esf
 		public SignaturePolicyId(DerObjectIdentifier sigPolicyIdentifier, OtherHashAlgAndValue sigPolicyHash,
 			params SigPolicyQualifierInfo[]	sigPolicyQualifiers)
 		{
-			if (sigPolicyIdentifier == null)
-				throw new ArgumentNullException(nameof(sigPolicyIdentifier));
-			if (sigPolicyHash == null)
-				throw new ArgumentNullException(nameof(sigPolicyHash));
+			m_sigPolicyIdentifier = sigPolicyIdentifier ?? throw new ArgumentNullException(nameof(sigPolicyIdentifier));
+            m_sigPolicyHash = sigPolicyHash ?? throw new ArgumentNullException(nameof(sigPolicyHash));
 
-			m_sigPolicyIdentifier = sigPolicyIdentifier;
-			m_sigPolicyHash = sigPolicyHash;
-
-			if (sigPolicyQualifiers != null)
+            if (sigPolicyQualifiers != null)
 			{
-				m_sigPolicyQualifiers = new DerSequence(sigPolicyQualifiers);
+				m_sigPolicyQualifiers = DerSequence.FromElements(sigPolicyQualifiers);
 			}
 		}
 
 		public SignaturePolicyId(DerObjectIdentifier sigPolicyIdentifier, OtherHashAlgAndValue sigPolicyHash,
 			IEnumerable<SigPolicyQualifierInfo> sigPolicyQualifiers)
 		{
-            if (sigPolicyIdentifier == null)
-                throw new ArgumentNullException(nameof(sigPolicyIdentifier));
-            if (sigPolicyHash == null)
-                throw new ArgumentNullException(nameof(sigPolicyHash));
-
-			m_sigPolicyIdentifier = sigPolicyIdentifier;
-			m_sigPolicyHash = sigPolicyHash;
+			m_sigPolicyIdentifier = sigPolicyIdentifier ?? throw new ArgumentNullException(nameof(sigPolicyIdentifier));
+            m_sigPolicyHash = sigPolicyHash ?? throw new ArgumentNullException(nameof(sigPolicyHash));
 
-			if (sigPolicyQualifiers != null)
+            if (sigPolicyQualifiers != null)
 			{
-				m_sigPolicyQualifiers = new DerSequence(Asn1EncodableVector.FromEnumerable(sigPolicyQualifiers));
+				m_sigPolicyQualifiers = DerSequence.FromVector(Asn1EncodableVector.FromEnumerable(sigPolicyQualifiers));
 			}
 		}
 
-		public DerObjectIdentifier SigPolicyIdentifier
-		{
-			get { return m_sigPolicyIdentifier; }
-		}
+		public DerObjectIdentifier SigPolicyIdentifier => m_sigPolicyIdentifier;
 
-		public OtherHashAlgAndValue SigPolicyHash
-		{
-			get { return m_sigPolicyHash; }
-		}
+		public OtherHashAlgAndValue SigPolicyHash => m_sigPolicyHash;
 
-		public SigPolicyQualifierInfo[] GetSigPolicyQualifiers()
-		{
-			return m_sigPolicyQualifiers?.MapElements(SigPolicyQualifierInfo.GetInstance);
-		}
+		public SigPolicyQualifierInfo[] GetSigPolicyQualifiers() =>
+			m_sigPolicyQualifiers?.MapElements(SigPolicyQualifierInfo.GetInstance);
 
 		public override Asn1Object ToAsn1Object()
 		{
-			Asn1EncodableVector v = new Asn1EncodableVector(
-				m_sigPolicyIdentifier, m_sigPolicyHash.ToAsn1Object());
-
-			if (m_sigPolicyQualifiers != null)
-			{
-				v.Add(m_sigPolicyQualifiers.ToAsn1Object());
-			}
-
+			Asn1EncodableVector v = new Asn1EncodableVector(3);
+			v.Add(m_sigPolicyIdentifier, m_sigPolicyHash);
+			v.AddOptional(m_sigPolicyQualifiers);
 			return new DerSequence(v);
 		}
 	}
diff --git a/crypto/src/asn1/esf/SignaturePolicyIdentifier.cs b/crypto/src/asn1/esf/SignaturePolicyIdentifier.cs
index 12257f2f0..eb6c0654c 100644
--- a/crypto/src/asn1/esf/SignaturePolicyIdentifier.cs
+++ b/crypto/src/asn1/esf/SignaturePolicyIdentifier.cs
@@ -17,50 +17,39 @@ namespace Org.BouncyCastle.Asn1.Esf
 	public class SignaturePolicyIdentifier
 		: Asn1Encodable, IAsn1Choice
 	{
-		private readonly SignaturePolicyId sigPolicy;
-
-		public static SignaturePolicyIdentifier GetInstance(
-			object obj)
+		public static SignaturePolicyIdentifier GetInstance(object obj)
 		{
-			if (obj == null || obj is SignaturePolicyIdentifier)
-				return (SignaturePolicyIdentifier) obj;
+			if (obj == null)
+				return null;
 
-			if (obj is SignaturePolicyId)
-				return new SignaturePolicyIdentifier((SignaturePolicyId) obj);
+			if (obj is SignaturePolicyIdentifier signaturePolicyIdentifier)
+				return signaturePolicyIdentifier;
 
-			if (obj is Asn1Null)
-				return new SignaturePolicyIdentifier();
+            if (obj is Asn1Null)
+                return new SignaturePolicyIdentifier();
 
-			throw new ArgumentException(
-				"Unknown object in 'SignaturePolicyIdentifier' factory: "
-                    + Platform.GetTypeName(obj),
-				"obj");
+			return new SignaturePolicyIdentifier(SignaturePolicyId.GetInstance(obj));
 		}
 
-		public SignaturePolicyIdentifier()
-		{
-			this.sigPolicy = null;
-		}
+        public static SignaturePolicyIdentifier GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return Asn1Utilities.GetInstanceFromChoice(taggedObject, declaredExplicit, GetInstance);
+        }
 
-		public SignaturePolicyIdentifier(
-			SignaturePolicyId signaturePolicyId)
-		{
-			if (signaturePolicyId == null)
-				throw new ArgumentNullException("signaturePolicyId");
+        private readonly SignaturePolicyId m_sigPolicy;
 
-			this.sigPolicy = signaturePolicyId;
-		}
-
-		public SignaturePolicyId SignaturePolicyId
+        public SignaturePolicyIdentifier()
 		{
-			get { return sigPolicy; }
+			m_sigPolicy = null;
 		}
 
-		public override Asn1Object ToAsn1Object()
+		public SignaturePolicyIdentifier(SignaturePolicyId signaturePolicyId)
 		{
-			return sigPolicy == null
-				?	DerNull.Instance
-				:	sigPolicy.ToAsn1Object();
-		}
+			m_sigPolicy = signaturePolicyId ?? throw new ArgumentNullException(nameof(signaturePolicyId));
+        }
+
+        public SignaturePolicyId SignaturePolicyId => m_sigPolicy;
+
+		public override Asn1Object ToAsn1Object() => m_sigPolicy?.ToAsn1Object() ?? DerNull.Instance;
 	}
 }
diff --git a/crypto/src/asn1/esf/SignerAttribute.cs b/crypto/src/asn1/esf/SignerAttribute.cs
index 03cdd4ba8..383b1d22e 100644
--- a/crypto/src/asn1/esf/SignerAttribute.cs
+++ b/crypto/src/asn1/esf/SignerAttribute.cs
@@ -1,70 +1,54 @@
 using System;
 
 using Org.BouncyCastle.Asn1.X509;
-using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Asn1.Esf
 {
-	public class SignerAttribute
+    public class SignerAttribute
 		: Asn1Encodable
 	{
-		private Asn1Sequence			claimedAttributes;
-		private AttributeCertificate	certifiedAttributes;
+        public static SignerAttribute GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is SignerAttribute signerAttribute)
+                return signerAttribute;
+            return new SignerAttribute(Asn1Sequence.GetInstance(obj), dummy: true);
+        }
 
-		public static SignerAttribute GetInstance(
-			object obj)
-		{
-			if (obj == null || obj is SignerAttribute)
-				return (SignerAttribute) obj;
-
-			if (obj is Asn1Sequence)
-				return new SignerAttribute(obj);
-
-			throw new ArgumentException(
-				"Unknown object in 'SignerAttribute' factory: "
-                + Platform.GetTypeName(obj),
-				"obj");
-		}
+        private readonly Asn1Sequence m_claimedAttributes;
+        private readonly AttributeCertificate m_certifiedAttributes;
 
-		private SignerAttribute(object obj)
+        private SignerAttribute(Asn1Sequence seq, bool dummy)
 		{
-			Asn1Sequence seq = (Asn1Sequence)obj;
-			Asn1TaggedObject taggedObject = (Asn1TaggedObject)seq[0];
+			Asn1TaggedObject taggedObject = Asn1TaggedObject.GetInstance(seq[0], Asn1Tags.ContextSpecific);
 			if (taggedObject.TagNo == 0)
 			{
-				claimedAttributes = Asn1Sequence.GetInstance(taggedObject, true);
+				m_claimedAttributes = Asn1Sequence.GetInstance(taggedObject, true);
 			}
 			else if (taggedObject.TagNo == 1)
 			{
-				certifiedAttributes = AttributeCertificate.GetInstance(taggedObject);
+				m_certifiedAttributes = AttributeCertificate.GetInstance(taggedObject, true);
 			}
 			else
 			{
-				throw new ArgumentException("illegal tag.", "obj");
+				throw new ArgumentException("illegal tag.", nameof(seq));
 			}
 		}
 
-		public SignerAttribute(
-			Asn1Sequence claimedAttributes)
+		public SignerAttribute(Asn1Sequence claimedAttributes)
 		{
-			this.claimedAttributes = claimedAttributes;
+			m_claimedAttributes = claimedAttributes ?? throw new ArgumentNullException(nameof(claimedAttributes));
 		}
 
-		public SignerAttribute(
-			AttributeCertificate certifiedAttributes)
+		public SignerAttribute(AttributeCertificate certifiedAttributes)
 		{
-			this.certifiedAttributes = certifiedAttributes;
+			m_certifiedAttributes = certifiedAttributes ?? throw new ArgumentNullException(nameof(certifiedAttributes));
 		}
 
-		public virtual Asn1Sequence ClaimedAttributes
-		{
-			get { return claimedAttributes; }
-		}
+		public virtual Asn1Sequence ClaimedAttributes => m_claimedAttributes;
 
-		public virtual AttributeCertificate CertifiedAttributes
-		{
-			get { return certifiedAttributes; }
-		}
+		public virtual AttributeCertificate CertifiedAttributes => m_certifiedAttributes;
 
 		/**
 		*
@@ -79,9 +63,9 @@ namespace Org.BouncyCastle.Asn1.Esf
 		*/
 		public override Asn1Object ToAsn1Object()
 		{
-			return claimedAttributes != null
-				?	new DerSequence(new DerTaggedObject(0, claimedAttributes))
-				:	new DerSequence(new DerTaggedObject(1, certifiedAttributes));
+			return m_claimedAttributes != null
+				?	new DerSequence(new DerTaggedObject(0, m_claimedAttributes))
+				:	new DerSequence(new DerTaggedObject(1, m_certifiedAttributes));
 		}
 	}
 }
diff --git a/crypto/src/asn1/esf/SignerLocation.cs b/crypto/src/asn1/esf/SignerLocation.cs
index 7b1300045..c4f5e6521 100644
--- a/crypto/src/asn1/esf/SignerLocation.cs
+++ b/crypto/src/asn1/esf/SignerLocation.cs
@@ -4,7 +4,7 @@ using Org.BouncyCastle.Asn1.X500;
 
 namespace Org.BouncyCastle.Asn1.Esf
 {
-	/**
+    /**
 	* Signer-Location attribute (RFC3126).
 	*
 	* <pre>
@@ -16,100 +16,81 @@ namespace Org.BouncyCastle.Asn1.Esf
 	*   PostalAddress ::= SEQUENCE SIZE(1..6) OF DirectoryString
 	* </pre>
 	*/
-	public class SignerLocation
-		: Asn1Encodable
-	{
-        private readonly DirectoryString countryName;
-        private readonly DirectoryString localityName;
-        private readonly Asn1Sequence postalAddress;
-
-		public SignerLocation(Asn1Sequence seq)
-		{
-			foreach (var element in seq)
-			{
-				var obj = Asn1TaggedObject.GetInstance(element, Asn1Tags.ContextSpecific);
-
-				switch (obj.TagNo)
-				{
-				case 0:
-					this.countryName = DirectoryString.GetInstance(obj, true);
-					break;
-				case 1:
-                    this.localityName = DirectoryString.GetInstance(obj, true);
-					break;
-				case 2:
-					bool isExplicit = obj.IsExplicit();	// handle erroneous implicitly tagged sequences
-					this.postalAddress = Asn1Sequence.GetInstance(obj, isExplicit);
-					if (postalAddress != null && postalAddress.Count > 6)
-						throw new ArgumentException("postal address must contain less than 6 strings");
-					break;
-				default:
-					throw new ArgumentException("illegal tag");
-				}
-			}
-		}
-
-        private SignerLocation(
-            DirectoryString countryName,
-            DirectoryString localityName,
-            Asn1Sequence postalAddress)
+    public class SignerLocation
+        : Asn1Encodable
+    {
+        public static SignerLocation GetInstance(object obj)
         {
-            if (postalAddress != null && postalAddress.Count > 6)
-                throw new ArgumentException("postal address must contain less than 6 strings");
-
-            this.countryName = countryName;
-            this.localityName = localityName;
-            this.postalAddress = postalAddress;
+            if (obj == null)
+                return null;
+            if (obj is SignerLocation signerLocation)
+                return signerLocation;
+            return new SignerLocation(Asn1Sequence.GetInstance(obj));
         }
 
-        public SignerLocation(
-            DirectoryString countryName,
-            DirectoryString localityName,
-            DirectoryString[] postalAddress)
-            : this(countryName, localityName, new DerSequence(postalAddress))
+        public static SignerLocation GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
         {
+            return new SignerLocation(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
         }
 
-        public SignerLocation(
-            DerUtf8String countryName,
-            DerUtf8String localityName,
-            Asn1Sequence postalAddress)
-            : this(DirectoryString.GetInstance(countryName), DirectoryString.GetInstance(localityName), postalAddress)
+        private readonly DirectoryString m_countryName;
+        private readonly DirectoryString m_localityName;
+        private readonly Asn1Sequence m_postalAddress;
+
+        public SignerLocation(Asn1Sequence seq)
         {
-        }
+            int count = seq.Count;
+            if (count < 0 || count > 3)
+                throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
 
-        public static SignerLocation GetInstance(object obj)
-		{
-			if (obj == null || obj is SignerLocation)
-				return (SignerLocation) obj;
+            int pos = 0;
 
-			return new SignerLocation(Asn1Sequence.GetInstance(obj));
-		}
+            m_countryName = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 0, true, DirectoryString.GetInstance);
+            m_localityName = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 1, true, DirectoryString.GetInstance);
 
-        public DirectoryString Country
-        {
-            get { return countryName; }
+            m_postalAddress = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 2, true, Asn1Sequence.GetInstance);
+            if (m_postalAddress != null)
+            {
+                if (m_postalAddress.Count > 6)
+                    throw new ArgumentException("postal address must contain less than 6 strings");
+
+                m_postalAddress.MapElements(element => DirectoryString.GetInstance(element.ToAsn1Object()));
+            }
+
+            if (pos != count)
+                throw new ArgumentException("Unexpected elements in sequence", nameof(seq));
         }
 
-        public DirectoryString Locality
+        private SignerLocation(DirectoryString countryName, DirectoryString localityName, Asn1Sequence postalAddress)
         {
-            get { return localityName; }
+            if (postalAddress != null && postalAddress.Count > 6)
+                throw new ArgumentException("postal address must contain less than 6 strings");
+
+            m_countryName = countryName;
+            m_localityName = localityName;
+            m_postalAddress = postalAddress;
         }
 
-        public DirectoryString[] GetPostal()
+        public SignerLocation(DirectoryString countryName, DirectoryString localityName, DirectoryString[] postalAddress)
+            : this(countryName, localityName, new DerSequence(postalAddress))
         {
-            if (postalAddress == null)
-                return null;
+        }
 
-			return postalAddress.MapElements(element => DirectoryString.GetInstance(element.ToAsn1Object()));
+        public SignerLocation(DerUtf8String countryName, DerUtf8String localityName, Asn1Sequence postalAddress)
+            : this(DirectoryString.GetInstance(countryName), DirectoryString.GetInstance(localityName), postalAddress)
+        {
         }
 
-		public Asn1Sequence PostalAddress
-		{
-			get { return postalAddress; }
-		}
+        public DirectoryString Country => m_countryName;
+
+        public DirectoryString Locality => m_localityName;
+
+        public DirectoryString[] GetPostal() =>
+            m_postalAddress?.MapElements(element => DirectoryString.GetInstance(element.ToAsn1Object()));
 
-		/**
+        public Asn1Sequence PostalAddress => m_postalAddress;
+
+        /**
 		* <pre>
 		*   SignerLocation ::= SEQUENCE {
 		*       countryName        [0] DirectoryString OPTIONAL,
@@ -126,13 +107,13 @@ namespace Org.BouncyCastle.Asn1.Esf
 		*         bmpString               BMPString (SIZE (1..MAX)) }
 		* </pre>
 		*/
-		public override Asn1Object ToAsn1Object()
-		{
-			Asn1EncodableVector v = new Asn1EncodableVector(3);
-            v.AddOptionalTagged(true, 0, countryName);
-            v.AddOptionalTagged(true, 1, localityName);
-            v.AddOptionalTagged(true, 2, postalAddress);
-			return new DerSequence(v);
-		}
-	}
+        public override Asn1Object ToAsn1Object()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector(3);
+            v.AddOptionalTagged(true, 0, m_countryName);
+            v.AddOptionalTagged(true, 1, m_localityName);
+            v.AddOptionalTagged(true, 2, m_postalAddress);
+            return DerSequence.FromVector(v);
+        }
+    }
 }