From 3b505be299fc4e147598605a9ee30c10a7e3eb85 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Thu, 20 Jun 2024 21:29:18 +0700 Subject: Refactoring in Asn1.Pkcs --- crypto/src/asn1/pkcs/Attribute.cs | 73 ++++----- crypto/src/asn1/pkcs/AuthenticatedSafe.cs | 57 +++---- crypto/src/asn1/pkcs/CertBag.cs | 29 ++-- crypto/src/asn1/pkcs/CertificationRequest.cs | 55 +++---- crypto/src/asn1/pkcs/CertificationRequestInfo.cs | 118 ++++++--------- crypto/src/asn1/pkcs/ContentInfo.cs | 56 ++++--- crypto/src/asn1/pkcs/CrlBag.cs | 25 ++-- crypto/src/asn1/pkcs/DHParameter.cs | 76 +++++----- crypto/src/asn1/pkcs/EncryptedData.cs | 81 ++++------ crypto/src/asn1/pkcs/EncryptedPrivateKeyInfo.cs | 55 ++++--- crypto/src/asn1/pkcs/EncryptionScheme.cs | 1 + crypto/src/asn1/pkcs/IssuerAndSerialNumber.cs | 72 ++++----- crypto/src/asn1/pkcs/KeyDerivationFunc.cs | 4 +- crypto/src/asn1/pkcs/MacData.cs | 90 +++++------ crypto/src/asn1/pkcs/PBEParameter.cs | 43 +++--- crypto/src/asn1/pkcs/PBES2Parameters.cs | 60 +++----- crypto/src/asn1/pkcs/PBKDF2Params.cs | 146 +++++++----------- crypto/src/asn1/pkcs/PKCS12PBEParams.cs | 66 ++++----- crypto/src/asn1/pkcs/Pfx.cs | 47 +++--- crypto/src/asn1/pkcs/PrivateKeyInfo.cs | 181 ++++++++--------------- crypto/src/asn1/pkcs/RC2CBCParameter.cs | 79 +++++----- crypto/src/asn1/pkcs/RSAESOAEPparams.cs | 161 +++++++++----------- crypto/src/asn1/pkcs/RSAPrivateKeyStructure.cs | 130 +++++++--------- crypto/src/asn1/pkcs/RSASSAPSSparams.cs | 167 +++++++++------------ crypto/src/asn1/pkcs/SafeBag.cs | 75 +++++----- crypto/src/asn1/pkcs/SignedData.cs | 140 +++++++----------- crypto/src/asn1/pkcs/SignerInfo.cs | 136 ++++++++--------- crypto/src/security/PbeUtilities.cs | 2 +- crypto/src/security/PrivateKeyFactory.cs | 3 +- crypto/src/security/PublicKeyFactory.cs | 2 +- crypto/test/src/crypto/test/Pkcs5Test.cs | 2 +- 31 files changed, 928 insertions(+), 1304 deletions(-) (limited to 'crypto') diff --git a/crypto/src/asn1/pkcs/Attribute.cs b/crypto/src/asn1/pkcs/Attribute.cs index 185828596..3bd4aa4e5 100644 --- a/crypto/src/asn1/pkcs/Attribute.cs +++ b/crypto/src/asn1/pkcs/Attribute.cs @@ -1,66 +1,46 @@ using System; -using Org.BouncyCastle.Utilities; - namespace Org.BouncyCastle.Asn1.Pkcs { public class AttributePkcs : Asn1Encodable { - private readonly DerObjectIdentifier attrType; - private readonly Asn1Set attrValues; - - /** - * return an Attribute object from the given object. - * - * @param o the object we want converted. - * @exception ArgumentException if the object cannot be converted. - */ - public static AttributePkcs GetInstance( - object obj) + public static AttributePkcs GetInstance(object obj) { - AttributePkcs attr = obj as AttributePkcs; - if (obj == null || attr != null) - { - return attr; - } + if (obj == null) + return null; + if (obj is AttributePkcs attributePkcs) + return attributePkcs; + return new AttributePkcs(Asn1Sequence.GetInstance(obj)); + } - Asn1Sequence seq = obj as Asn1Sequence; - if (seq != null) - { - return new AttributePkcs(seq); - } + public static AttributePkcs GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + return new AttributePkcs(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); + } - throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj"); - } + private readonly DerObjectIdentifier m_attrType; + private readonly Asn1Set m_attrValues; - private AttributePkcs( - Asn1Sequence seq) + private AttributePkcs(Asn1Sequence seq) { - if (seq.Count != 2) - throw new ArgumentException("Wrong number of elements in sequence", "seq"); + int count = seq.Count; + if (count != 2) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); - attrType = DerObjectIdentifier.GetInstance(seq[0]); - attrValues = Asn1Set.GetInstance(seq[1]); + m_attrType = DerObjectIdentifier.GetInstance(seq[0]); + m_attrValues = Asn1Set.GetInstance(seq[1]); } - public AttributePkcs( - DerObjectIdentifier attrType, - Asn1Set attrValues) + public AttributePkcs(DerObjectIdentifier attrType, Asn1Set attrValues) { - this.attrType = attrType; - this.attrValues = attrValues; + m_attrType = attrType ?? throw new ArgumentNullException(nameof(attrType)); + m_attrValues = attrValues ?? throw new ArgumentNullException(nameof(attrValues)); } - public DerObjectIdentifier AttrType - { - get { return attrType; } - } + public DerObjectIdentifier AttrType => m_attrType; - public Asn1Set AttrValues - { - get { return attrValues; } - } + public Asn1Set AttrValues => m_attrValues; /** * Produce an object suitable for an Asn1OutputStream. @@ -71,9 +51,6 @@ namespace Org.BouncyCastle.Asn1.Pkcs * } * */ - public override Asn1Object ToAsn1Object() - { - return new DerSequence(attrType, attrValues); - } + public override Asn1Object ToAsn1Object() => new DerSequence(m_attrType, m_attrValues); } } diff --git a/crypto/src/asn1/pkcs/AuthenticatedSafe.cs b/crypto/src/asn1/pkcs/AuthenticatedSafe.cs index 6f3b4c8c3..0d8379179 100644 --- a/crypto/src/asn1/pkcs/AuthenticatedSafe.cs +++ b/crypto/src/asn1/pkcs/AuthenticatedSafe.cs @@ -1,63 +1,46 @@ -using System; - -using Org.BouncyCastle.Asn1; - namespace Org.BouncyCastle.Asn1.Pkcs { public class AuthenticatedSafe : Asn1Encodable { - private static ContentInfo[] Copy(ContentInfo[] info) - { - return (ContentInfo[])info.Clone(); - } - public static AuthenticatedSafe GetInstance(object obj) { - if (obj is AuthenticatedSafe) - return (AuthenticatedSafe)obj; if (obj == null) return null; + if (obj is AuthenticatedSafe authenticatedSafe) + return authenticatedSafe; return new AuthenticatedSafe(Asn1Sequence.GetInstance(obj)); } - private readonly ContentInfo[] info; - private readonly bool isBer; - - private AuthenticatedSafe(Asn1Sequence seq) + public static AuthenticatedSafe GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) { - info = new ContentInfo[seq.Count]; - - for (int i = 0; i != info.Length; i++) - { - info[i] = ContentInfo.GetInstance(seq[i]); - } - - isBer = seq is BerSequence; + return new AuthenticatedSafe(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); } - public AuthenticatedSafe( - ContentInfo[] info) + private readonly ContentInfo[] m_info; + private readonly bool m_isBer; + + private AuthenticatedSafe(Asn1Sequence seq) { - this.info = Copy(info); - this.isBer = true; + m_info = seq.MapElements(ContentInfo.GetInstance); + m_isBer = seq is BerSequence; } - public ContentInfo[] GetContentInfo() + public AuthenticatedSafe(ContentInfo[] info) { - return Copy(info); + m_info = Copy(info); + m_isBer = true; } + public ContentInfo[] GetContentInfo() => Copy(m_info); + public override Asn1Object ToAsn1Object() { - if (isBer) - { - return new BerSequence(info); - } - - // TODO bc-java uses DL sequence - //return new DLSequence(info); - return new DerSequence(info); + return m_isBer + ? new BerSequence(m_info) + : new DLSequence(m_info); } + + private static ContentInfo[] Copy(ContentInfo[] info) => (ContentInfo[])info.Clone(); } } diff --git a/crypto/src/asn1/pkcs/CertBag.cs b/crypto/src/asn1/pkcs/CertBag.cs index 129a73ada..bce67cd0a 100644 --- a/crypto/src/asn1/pkcs/CertBag.cs +++ b/crypto/src/asn1/pkcs/CertBag.cs @@ -7,38 +7,43 @@ namespace Org.BouncyCastle.Asn1.Pkcs { public static CertBag GetInstance(object obj) { - if (obj is CertBag certBag) - return certBag; if (obj == null) return null; + if (obj is CertBag certBag) + return certBag; return new CertBag(Asn1Sequence.GetInstance(obj)); } + public static CertBag GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + return new CertBag(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); + } + private readonly DerObjectIdentifier m_certID; private readonly Asn1Object m_certValue; private CertBag(Asn1Sequence seq) { - if (seq.Count != 2) - throw new ArgumentException("Wrong number of elements in sequence", nameof(seq)); + int count = seq.Count; + if (count != 2) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); - this.m_certID = DerObjectIdentifier.GetInstance(seq[0]); - this.m_certValue = Asn1TaggedObject.GetInstance(seq[1]).GetExplicitBaseObject().ToAsn1Object(); + m_certID = DerObjectIdentifier.GetInstance(seq[0]); + m_certValue = Asn1TaggedObject.GetInstance(seq[1], Asn1Tags.ContextSpecific, 0) + .GetExplicitBaseObject().ToAsn1Object(); } public CertBag(DerObjectIdentifier certID, Asn1Object certValue) { - m_certID = certID; - m_certValue = certValue; + m_certID = certID ?? throw new ArgumentNullException(nameof(certID)); + m_certValue = certValue ?? throw new ArgumentNullException(nameof(certValue)); } public virtual DerObjectIdentifier CertID => m_certID; + // TODO[api] Prefer returning Asn1Encodable public virtual Asn1Object CertValue => m_certValue; - public override Asn1Object ToAsn1Object() - { - return new DerSequence(m_certID, new DerTaggedObject(0, m_certValue)); - } + public override Asn1Object ToAsn1Object() => new DerSequence(m_certID, new DerTaggedObject(0, m_certValue)); } } diff --git a/crypto/src/asn1/pkcs/CertificationRequest.cs b/crypto/src/asn1/pkcs/CertificationRequest.cs index 8c4248d36..9a7c28ab1 100644 --- a/crypto/src/asn1/pkcs/CertificationRequest.cs +++ b/crypto/src/asn1/pkcs/CertificationRequest.cs @@ -14,31 +14,34 @@ namespace Org.BouncyCastle.Asn1.Pkcs * } * */ + // TODO[api] Stop subclassing this class public class CertificationRequest : Asn1Encodable { - protected CertificationRequestInfo reqInfo; - protected AlgorithmIdentifier sigAlgId; - protected DerBitString sigBits; - - public static CertificationRequest GetInstance( - object obj) + public static CertificationRequest GetInstance(object obj) { if (obj == null) return null; - if (obj is CertificationRequest) - return (CertificationRequest)obj; + if (obj is CertificationRequest certificationRequest) + return certificationRequest; return new CertificationRequest(Asn1Sequence.GetInstance(obj)); } - protected CertificationRequest() + public static CertificationRequest GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + return new CertificationRequest(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); + } + + protected CertificationRequestInfo reqInfo; + protected AlgorithmIdentifier sigAlgId; + protected DerBitString sigBits; + + protected CertificationRequest() { } - public CertificationRequest( - CertificationRequestInfo requestInfo, - AlgorithmIdentifier algorithm, - DerBitString signature) + public CertificationRequest(CertificationRequestInfo requestInfo, AlgorithmIdentifier algorithm, + DerBitString signature) { this.reqInfo = requestInfo; this.sigAlgId = algorithm; @@ -55,29 +58,15 @@ namespace Org.BouncyCastle.Asn1.Pkcs sigBits = DerBitString.GetInstance(seq[2]); } - public CertificationRequestInfo GetCertificationRequestInfo() - { - return reqInfo; - } + // TODO[api] Rename as a property + public CertificationRequestInfo GetCertificationRequestInfo() => reqInfo; - public AlgorithmIdentifier SignatureAlgorithm - { - get { return sigAlgId; } - } + public AlgorithmIdentifier SignatureAlgorithm => sigAlgId; - public DerBitString Signature - { - get { return sigBits; } - } + public DerBitString Signature => sigBits; - public byte[] GetSignatureOctets() - { - return sigBits.GetOctets(); - } + public byte[] GetSignatureOctets() => sigBits.GetOctets(); - public override Asn1Object ToAsn1Object() - { - return new DerSequence(reqInfo, sigAlgId, sigBits); - } + public override Asn1Object ToAsn1Object() => new DerSequence(reqInfo, sigAlgId, sigBits); } } diff --git a/crypto/src/asn1/pkcs/CertificationRequestInfo.cs b/crypto/src/asn1/pkcs/CertificationRequestInfo.cs index 196d9f4e5..53bdffdaa 100644 --- a/crypto/src/asn1/pkcs/CertificationRequestInfo.cs +++ b/crypto/src/asn1/pkcs/CertificationRequestInfo.cs @@ -25,107 +25,83 @@ namespace Org.BouncyCastle.Asn1.Pkcs public class CertificationRequestInfo : Asn1Encodable { - internal DerInteger version = DerInteger.Zero; - internal X509Name subject; - internal SubjectPublicKeyInfo subjectPKInfo; - internal Asn1Set attributes; - public static CertificationRequestInfo GetInstance(object obj) { - if (obj is CertificationRequestInfo) - return (CertificationRequestInfo)obj; - if (obj != null) - return new CertificationRequestInfo(Asn1Sequence.GetInstance(obj)); - return null; + if (obj == null) + return null; + if (obj is CertificationRequestInfo certificationRequestInfo) + return certificationRequestInfo; + return new CertificationRequestInfo(Asn1Sequence.GetInstance(obj)); } - public CertificationRequestInfo( - X509Name subject, - SubjectPublicKeyInfo pkInfo, - Asn1Set attributes) + public static CertificationRequestInfo GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) { - this.subject = subject; - this.subjectPKInfo = pkInfo; - this.attributes = attributes; + return new CertificationRequestInfo(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); + } - ValidateAttributes(attributes); + private readonly DerInteger m_version; + private readonly X509Name m_subject; + private readonly SubjectPublicKeyInfo m_subjectPKInfo; + private readonly Asn1Set m_attributes; - if (subject == null || version == null || subjectPKInfo == null) - { - throw new ArgumentException( - "Not all mandatory fields set in CertificationRequestInfo generator."); - } + public CertificationRequestInfo(X509Name subject, SubjectPublicKeyInfo pkInfo, Asn1Set attributes) + { + m_version = DerInteger.Zero; + m_subject = subject ?? throw new ArgumentNullException(nameof(subject)); + m_subjectPKInfo = pkInfo ?? throw new ArgumentNullException(nameof(pkInfo)); + m_attributes = ValidateAttributes(attributes); } - private CertificationRequestInfo( - Asn1Sequence seq) + private CertificationRequestInfo(Asn1Sequence seq) { - version = (DerInteger) seq[0]; + int count = seq.Count, pos = 0; + if (count < 3 || count > 4) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); - subject = X509Name.GetInstance(seq[1]); - subjectPKInfo = SubjectPublicKeyInfo.GetInstance(seq[2]); + m_version = DerInteger.GetInstance(seq[pos++]); + m_subject = X509Name.GetInstance(seq[pos++]); + m_subjectPKInfo = SubjectPublicKeyInfo.GetInstance(seq[pos++]); - // - // some CertificationRequestInfo objects seem to treat this field - // as optional. - // - if (seq.Count > 3) - { - Asn1TaggedObject tagobj = (Asn1TaggedObject)seq[3]; - attributes = Asn1Set.GetInstance(tagobj, false); - } + // NOTE: some CertificationRequestInfo objects seem to treat this field as optional. + m_attributes = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 0, false, Asn1Set.GetInstance); - ValidateAttributes(attributes); + if (pos != count) + throw new ArgumentException("Unexpected elements in sequence", nameof(seq)); - if (subject == null || version == null || subjectPKInfo == null) - { - throw new ArgumentException( - "Not all mandatory fields set in CertificationRequestInfo generator."); - } + ValidateAttributes(m_attributes); } - public DerInteger Version - { - get { return version; } - } + public DerInteger Version => m_version; - public X509Name Subject - { - get { return subject; } - } + public X509Name Subject => m_subject; - public SubjectPublicKeyInfo SubjectPublicKeyInfo - { - get { return subjectPKInfo; } - } + public SubjectPublicKeyInfo SubjectPublicKeyInfo => m_subjectPKInfo; - public Asn1Set Attributes - { - get { return attributes; } - } + public Asn1Set Attributes => m_attributes; public override Asn1Object ToAsn1Object() { - Asn1EncodableVector v = new Asn1EncodableVector(version, subject, subjectPKInfo); - v.AddOptionalTagged(false, 0, attributes); + Asn1EncodableVector v = new Asn1EncodableVector(4); + v.Add(m_version, m_subject, m_subjectPKInfo); + v.AddOptionalTagged(false, 0, m_attributes); return new DerSequence(v); } - private static void ValidateAttributes(Asn1Set attributes) + private static Asn1Set ValidateAttributes(Asn1Set attributes) { - if (attributes == null) - return; - - foreach (Asn1Encodable ae in attributes) + if (attributes != null) { - Asn1Object obj = ae.ToAsn1Object(); - AttributePkcs attr = AttributePkcs.GetInstance(obj); - if (attr.AttrType.Equals(PkcsObjectIdentifiers.Pkcs9AtChallengePassword)) + foreach (var element in attributes) { - if (attr.AttrValues.Count != 1) - throw new ArgumentException("challengePassword attribute must have one value"); + AttributePkcs attr = AttributePkcs.GetInstance(element); + if (PkcsObjectIdentifiers.Pkcs9AtChallengePassword.Equals(attr.AttrType)) + { + if (attr.AttrValues.Count != 1) + throw new ArgumentException("challengePassword attribute must have one value"); + } } } + return attributes; } } } diff --git a/crypto/src/asn1/pkcs/ContentInfo.cs b/crypto/src/asn1/pkcs/ContentInfo.cs index 0a19306f2..faf2360cc 100644 --- a/crypto/src/asn1/pkcs/ContentInfo.cs +++ b/crypto/src/asn1/pkcs/ContentInfo.cs @@ -1,11 +1,10 @@ +using System; + namespace Org.BouncyCastle.Asn1.Pkcs { public class ContentInfo : Asn1Encodable { - private readonly DerObjectIdentifier contentType; - private readonly Asn1Encodable content; - public static ContentInfo GetInstance(object obj) { if (obj == null) @@ -15,54 +14,51 @@ namespace Org.BouncyCastle.Asn1.Pkcs return new ContentInfo(Asn1Sequence.GetInstance(obj)); } - private ContentInfo( - Asn1Sequence seq) + public static ContentInfo GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + return new ContentInfo(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); + } + + private readonly DerObjectIdentifier m_contentType; + private readonly Asn1Encodable m_content; + + private ContentInfo(Asn1Sequence seq) { - contentType = (DerObjectIdentifier) seq[0]; + int count = seq.Count; + if (count < 1 || count > 2) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); + + m_contentType = DerObjectIdentifier.GetInstance(seq[0]); if (seq.Count > 1) { - content = ((Asn1TaggedObject) seq[1]).GetExplicitBaseObject(); + m_content = Asn1TaggedObject.GetInstance(seq[1], Asn1Tags.ContextSpecific, 0).GetExplicitBaseObject(); } } - public ContentInfo( - DerObjectIdentifier contentType, - Asn1Encodable content) + public ContentInfo(DerObjectIdentifier contentType, Asn1Encodable content) { - this.contentType = contentType; - this.content = content; + m_contentType = contentType ?? throw new ArgumentNullException(nameof(contentType)); + m_content = content; } - public DerObjectIdentifier ContentType - { - get { return contentType; } - } + public DerObjectIdentifier ContentType => m_contentType; - public Asn1Encodable Content - { - get { return content; } - } + public Asn1Encodable Content => m_content; /** * Produce an object suitable for an Asn1OutputStream. *
          * ContentInfo ::= Sequence {
          *          contentType ContentType,
-         *          content
-         *          [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
+         *          content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
          * 
*/ public override Asn1Object ToAsn1Object() { - Asn1EncodableVector v = new Asn1EncodableVector(contentType); - - if (content != null) - { - v.Add(new BerTaggedObject(0, content)); - } - - return new BerSequence(v); + return m_content == null + ? new BerSequence(m_contentType) + : new BerSequence(m_contentType, new BerTaggedObject(0, m_content)); } } } diff --git a/crypto/src/asn1/pkcs/CrlBag.cs b/crypto/src/asn1/pkcs/CrlBag.cs index 0198c341c..28cc19fb1 100644 --- a/crypto/src/asn1/pkcs/CrlBag.cs +++ b/crypto/src/asn1/pkcs/CrlBag.cs @@ -7,38 +7,41 @@ namespace Org.BouncyCastle.Asn1.Pkcs { public static CrlBag GetInstance(object obj) { - if (obj is CrlBag crlBag) - return crlBag; if (obj == null) return null; + if (obj is CrlBag crlBag) + return crlBag; return new CrlBag(Asn1Sequence.GetInstance(obj)); } + public static CrlBag GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + return new CrlBag(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); + } + private readonly DerObjectIdentifier m_crlID; private readonly Asn1Encodable m_crlValue; private CrlBag(Asn1Sequence seq) { - if (seq.Count != 2) - throw new ArgumentException("Wrong number of elements in sequence", nameof(seq)); + int count = seq.Count; + if (count != 2) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); m_crlID = DerObjectIdentifier.GetInstance(seq[0]); - m_crlValue = Asn1TaggedObject.GetInstance(seq[1]).GetExplicitBaseObject(); + m_crlValue = Asn1TaggedObject.GetInstance(seq[1], Asn1Tags.ContextSpecific, 0).GetExplicitBaseObject(); } public CrlBag(DerObjectIdentifier crlID, Asn1Encodable crlValue) { - m_crlID = crlID; - m_crlValue = crlValue; + m_crlID = crlID ?? throw new ArgumentNullException(nameof(crlID)); + m_crlValue = crlValue ?? throw new ArgumentNullException(nameof(crlValue)); } public virtual DerObjectIdentifier CrlID => m_crlID; public virtual Asn1Encodable CrlValue => m_crlValue; - public override Asn1Object ToAsn1Object() - { - return new DerSequence(m_crlID, new DerTaggedObject(0, m_crlValue)); - } + public override Asn1Object ToAsn1Object() => new DerSequence(m_crlID, new DerTaggedObject(0, m_crlValue)); } } diff --git a/crypto/src/asn1/pkcs/DHParameter.cs b/crypto/src/asn1/pkcs/DHParameter.cs index 7a07a18b0..43a6129d4 100644 --- a/crypto/src/asn1/pkcs/DHParameter.cs +++ b/crypto/src/asn1/pkcs/DHParameter.cs @@ -1,3 +1,5 @@ +using System; + using Org.BouncyCastle.Math; namespace Org.BouncyCastle.Asn1.Pkcs @@ -5,59 +7,63 @@ namespace Org.BouncyCastle.Asn1.Pkcs public class DHParameter : Asn1Encodable { - internal DerInteger p, g, l; + public static DHParameter GetInstance(object obj) + { + if (obj == null) + return null; + if (obj is DHParameter dhParameter) + return dhParameter; +#pragma warning disable CS0618 // Type or member is obsolete + return new DHParameter(Asn1Sequence.GetInstance(obj)); +#pragma warning restore CS0618 // Type or member is obsolete + } - public DHParameter( - BigInteger p, - BigInteger g, - int l) + public static DHParameter GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) { - this.p = new DerInteger(p); - this.g = new DerInteger(g); +#pragma warning disable CS0618 // Type or member is obsolete + return new DHParameter(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); +#pragma warning restore CS0618 // Type or member is obsolete + } + + private readonly DerInteger m_p, m_g, m_l; + + public DHParameter(BigInteger p, BigInteger g, int l) + { + m_p = new DerInteger(p); + m_g = new DerInteger(g); if (l != 0) { - this.l = new DerInteger(l); + m_l = new DerInteger(l); } } - public DHParameter( - Asn1Sequence seq) + [Obsolete("Use 'GetInstance' instead")] + public DHParameter(Asn1Sequence seq) { - var e = seq.GetEnumerator(); - - e.MoveNext(); - p = (DerInteger)e.Current; + int count = seq.Count, pos = 0; + if (count < 2 || count > 3) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); - e.MoveNext(); - g = (DerInteger)e.Current; + m_p = DerInteger.GetInstance(seq[pos++]); + m_g = DerInteger.GetInstance(seq[pos++]); + m_l = Asn1Utilities.ReadOptional(seq, ref pos, DerInteger.GetOptional); - if (e.MoveNext()) - { - l = (DerInteger) e.Current; - } + if (pos != count) + throw new ArgumentException("Unexpected elements in sequence", nameof(seq)); } - public BigInteger P - { - get { return p.PositiveValue; } - } + public BigInteger P => m_p.PositiveValue; - public BigInteger G - { - get { return g.PositiveValue; } - } + public BigInteger G => m_g.PositiveValue; - public BigInteger L - { - get { return l == null ? null : l.PositiveValue; } - } + public BigInteger L => m_l?.PositiveValue; public override Asn1Object ToAsn1Object() { - Asn1EncodableVector v = new Asn1EncodableVector(p, g); - v.AddOptional(l); - return new DerSequence(v); + return m_l == null + ? new DerSequence(m_p, m_g) + : new DerSequence(m_p, m_g, m_l); } } } diff --git a/crypto/src/asn1/pkcs/EncryptedData.cs b/crypto/src/asn1/pkcs/EncryptedData.cs index f75975d5a..0b971eeeb 100644 --- a/crypto/src/asn1/pkcs/EncryptedData.cs +++ b/crypto/src/asn1/pkcs/EncryptedData.cs @@ -1,7 +1,6 @@ using System; using Org.BouncyCastle.Asn1.X509; -using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Asn1.Pkcs { @@ -26,78 +25,60 @@ namespace Org.BouncyCastle.Asn1.Pkcs public class EncryptedData : Asn1Encodable { - private readonly Asn1Sequence data; -// private readonly DerObjectIdentifier bagId; -// private readonly Asn1Object bagValue; + private readonly Asn1Sequence m_data; + // private readonly DerObjectIdentifier bagId; + // private readonly Asn1Object bagValue; - public static EncryptedData GetInstance( - object obj) + public static EncryptedData GetInstance(object obj) { - if (obj is EncryptedData) - { - return (EncryptedData) obj; - } - - if (obj is Asn1Sequence) - { - return new EncryptedData((Asn1Sequence) obj); - } + if (obj == null) + return null; + if (obj is EncryptedData encryptedData) + return encryptedData; + return new EncryptedData(Asn1Sequence.GetInstance(obj)); + } - throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj"); - } + public static EncryptedData GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + return new EncryptedData(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); + } - private EncryptedData( - Asn1Sequence seq) + private EncryptedData(Asn1Sequence seq) { - if (seq.Count != 2) - throw new ArgumentException("Wrong number of elements in sequence", "seq"); + int count = seq.Count; + if (count != 2) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); - DerInteger version = (DerInteger)seq[0]; - if (!version.HasValue(0)) + DerInteger version = DerInteger.GetInstance(seq[0]); + if (!version.HasValue(0)) throw new ArgumentException("sequence not version 0"); - this.data = (Asn1Sequence) seq[1]; + m_data = Asn1Sequence.GetInstance(seq[1]); } - public EncryptedData( - DerObjectIdentifier contentType, - AlgorithmIdentifier encryptionAlgorithm, - Asn1Encodable content) + public EncryptedData(DerObjectIdentifier contentType, AlgorithmIdentifier encryptionAlgorithm, + Asn1Encodable content) { - data = new BerSequence( - contentType, - encryptionAlgorithm.ToAsn1Object(), - new BerTaggedObject(false, 0, content)); + m_data = new BerSequence(contentType, encryptionAlgorithm, new BerTaggedObject(false, 0, content)); } - public DerObjectIdentifier ContentType - { - get { return (DerObjectIdentifier) data[0]; } - } + public DerObjectIdentifier ContentType => DerObjectIdentifier.GetInstance(m_data[0]); - public AlgorithmIdentifier EncryptionAlgorithm - { - get { return AlgorithmIdentifier.GetInstance(data[1]); } - } + public AlgorithmIdentifier EncryptionAlgorithm => AlgorithmIdentifier.GetInstance(m_data[1]); public Asn1OctetString Content { get { - if (data.Count == 3) - { - Asn1TaggedObject o = (Asn1TaggedObject)data[2]; + if (m_data.Count != 3) + return null; - return Asn1OctetString.GetInstance(o, false); - } + Asn1TaggedObject tagged = Asn1TaggedObject.GetInstance(m_data[2], Asn1Tags.ContextSpecific, 0); - return null; + return Asn1OctetString.GetInstance(tagged, declaredExplicit: false); } } - public override Asn1Object ToAsn1Object() - { - return new BerSequence(DerInteger.Zero, data); - } + public override Asn1Object ToAsn1Object() => new BerSequence(DerInteger.Zero, m_data); } } diff --git a/crypto/src/asn1/pkcs/EncryptedPrivateKeyInfo.cs b/crypto/src/asn1/pkcs/EncryptedPrivateKeyInfo.cs index bf0e1aaeb..39f3e9c3e 100644 --- a/crypto/src/asn1/pkcs/EncryptedPrivateKeyInfo.cs +++ b/crypto/src/asn1/pkcs/EncryptedPrivateKeyInfo.cs @@ -7,26 +7,6 @@ namespace Org.BouncyCastle.Asn1.Pkcs public class EncryptedPrivateKeyInfo : Asn1Encodable { - private readonly AlgorithmIdentifier algId; - private readonly Asn1OctetString data; - - private EncryptedPrivateKeyInfo(Asn1Sequence seq) - { - if (seq.Count != 2) - throw new ArgumentException("Wrong number of elements in sequence", "seq"); - - algId = AlgorithmIdentifier.GetInstance(seq[0]); - data = Asn1OctetString.GetInstance(seq[1]); - } - - public EncryptedPrivateKeyInfo( - AlgorithmIdentifier algId, - byte[] encoding) - { - this.algId = algId; - this.data = new DerOctetString(encoding); - } - public static EncryptedPrivateKeyInfo GetInstance(object obj) { if (obj == null) @@ -36,16 +16,34 @@ namespace Org.BouncyCastle.Asn1.Pkcs return new EncryptedPrivateKeyInfo(Asn1Sequence.GetInstance(obj)); } - public AlgorithmIdentifier EncryptionAlgorithm - { - get { return algId; } - } + public static EncryptedPrivateKeyInfo GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + return new EncryptedPrivateKeyInfo(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); + } - public byte[] GetEncryptedData() + private readonly AlgorithmIdentifier m_encryptionAlgorithm; + private readonly Asn1OctetString m_encryptedData; + + private EncryptedPrivateKeyInfo(Asn1Sequence seq) + { + int count = seq.Count; + if (count != 2) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); + + m_encryptionAlgorithm = AlgorithmIdentifier.GetInstance(seq[0]); + m_encryptedData = Asn1OctetString.GetInstance(seq[1]); + } + + public EncryptedPrivateKeyInfo(AlgorithmIdentifier algId, byte[] encoding) { - return data.GetOctets(); + m_encryptionAlgorithm = algId ?? throw new ArgumentNullException(nameof(algId)); + m_encryptedData = new DerOctetString(encoding); } + public AlgorithmIdentifier EncryptionAlgorithm => m_encryptionAlgorithm; + + public byte[] GetEncryptedData() => m_encryptedData.GetOctets(); + /** * Produce an object suitable for an Asn1OutputStream. *
@@ -61,9 +59,6 @@ namespace Org.BouncyCastle.Asn1.Pkcs
          * }
          * 
*/ - public override Asn1Object ToAsn1Object() - { - return new DerSequence(algId, data); - } + public override Asn1Object ToAsn1Object() => new DerSequence(m_encryptionAlgorithm, m_encryptedData); } } diff --git a/crypto/src/asn1/pkcs/EncryptionScheme.cs b/crypto/src/asn1/pkcs/EncryptionScheme.cs index a073f8c17..9834e1523 100644 --- a/crypto/src/asn1/pkcs/EncryptionScheme.cs +++ b/crypto/src/asn1/pkcs/EncryptionScheme.cs @@ -2,6 +2,7 @@ using Org.BouncyCastle.Asn1.X509; namespace Org.BouncyCastle.Asn1.Pkcs { + // TODO[api] This is not supposed to be a separate type; remove and use AlgorithmIdentifier public class EncryptionScheme : AlgorithmIdentifier { diff --git a/crypto/src/asn1/pkcs/IssuerAndSerialNumber.cs b/crypto/src/asn1/pkcs/IssuerAndSerialNumber.cs index da863cb62..0a2c05d41 100644 --- a/crypto/src/asn1/pkcs/IssuerAndSerialNumber.cs +++ b/crypto/src/asn1/pkcs/IssuerAndSerialNumber.cs @@ -2,71 +2,55 @@ using System; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Math; -using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Asn1.Pkcs { public class IssuerAndSerialNumber : Asn1Encodable { - private readonly X509Name name; - private readonly DerInteger certSerialNumber; - - public static IssuerAndSerialNumber GetInstance( - object obj) + public static IssuerAndSerialNumber GetInstance(object obj) { - if (obj is IssuerAndSerialNumber) - { - return (IssuerAndSerialNumber) obj; - } + if (obj == null) + return null; + if (obj is IssuerAndSerialNumber issuerAndSerialNumber) + return issuerAndSerialNumber; + return new IssuerAndSerialNumber(Asn1Sequence.GetInstance(obj)); + } - if (obj is Asn1Sequence) - { - return new IssuerAndSerialNumber((Asn1Sequence) obj); - } + public static IssuerAndSerialNumber GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + return new IssuerAndSerialNumber(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); + } - throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj"); - } + private readonly X509Name m_name; + private readonly DerInteger m_certSerialNumber; - private IssuerAndSerialNumber( - Asn1Sequence seq) + private IssuerAndSerialNumber(Asn1Sequence seq) { - if (seq.Count != 2) - throw new ArgumentException("Wrong number of elements in sequence", "seq"); + int count = seq.Count; + if (count != 2) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); - this.name = X509Name.GetInstance(seq[0]); - this.certSerialNumber = DerInteger.GetInstance(seq[1]); + m_name = X509Name.GetInstance(seq[0]); + m_certSerialNumber = DerInteger.GetInstance(seq[1]); } - public IssuerAndSerialNumber( - X509Name name, - BigInteger certSerialNumber) + public IssuerAndSerialNumber(X509Name name, BigInteger certSerialNumber) { - this.name = name; - this.certSerialNumber = new DerInteger(certSerialNumber); + m_name = name ?? throw new ArgumentNullException(nameof(name)); + m_certSerialNumber = new DerInteger(certSerialNumber); } - public IssuerAndSerialNumber( - X509Name name, - DerInteger certSerialNumber) + public IssuerAndSerialNumber(X509Name name, DerInteger certSerialNumber) { - this.name = name; - this.certSerialNumber = certSerialNumber; + m_name = name ?? throw new ArgumentNullException(nameof(name)); + m_certSerialNumber = certSerialNumber ?? throw new ArgumentNullException(nameof(certSerialNumber)); } - public X509Name Name - { - get { return name; } - } + public X509Name Name => m_name; - public DerInteger CertificateSerialNumber - { - get { return certSerialNumber; } - } + public DerInteger CertificateSerialNumber => m_certSerialNumber; - public override Asn1Object ToAsn1Object() - { - return new DerSequence(name, certSerialNumber); - } + public override Asn1Object ToAsn1Object() => new DerSequence(m_name, m_certSerialNumber); } } diff --git a/crypto/src/asn1/pkcs/KeyDerivationFunc.cs b/crypto/src/asn1/pkcs/KeyDerivationFunc.cs index 9fc89853b..64672df54 100644 --- a/crypto/src/asn1/pkcs/KeyDerivationFunc.cs +++ b/crypto/src/asn1/pkcs/KeyDerivationFunc.cs @@ -1,9 +1,9 @@ -using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.X509; namespace Org.BouncyCastle.Asn1.Pkcs { - public class KeyDerivationFunc + // TODO[api] This is not supposed to be a separate type; remove and use AlgorithmIdentifier + public class KeyDerivationFunc : AlgorithmIdentifier { internal KeyDerivationFunc(Asn1Sequence seq) diff --git a/crypto/src/asn1/pkcs/MacData.cs b/crypto/src/asn1/pkcs/MacData.cs index c4b7df176..d122dc45e 100644 --- a/crypto/src/asn1/pkcs/MacData.cs +++ b/crypto/src/asn1/pkcs/MacData.cs @@ -2,73 +2,56 @@ using System; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Math; -using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Asn1.Pkcs { public class MacData : Asn1Encodable { - internal DigestInfo digInfo; - internal byte[] salt; - internal BigInteger iterationCount; - - public static MacData GetInstance( - object obj) + public static MacData GetInstance(object obj) { - if (obj is MacData) - { - return (MacData) obj; - } + if (obj == null) + return null; + if (obj is MacData macData) + return macData; + return new MacData(Asn1Sequence.GetInstance(obj)); + } - if (obj is Asn1Sequence) - { - return new MacData((Asn1Sequence) obj); - } + public static MacData GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) + { + return new MacData(Asn1Sequence.GetInstance(taggedObject, declaredExplicit)); + } - throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj"); - } + private readonly DigestInfo m_digInfo; + private readonly Asn1OctetString m_salt; + private readonly DerInteger m_iterationCount; - private MacData( - Asn1Sequence seq) + private MacData(Asn1Sequence seq) { - this.digInfo = DigestInfo.GetInstance(seq[0]); - this.salt = ((Asn1OctetString) seq[1]).GetOctets(); + int count = seq.Count, pos = 0; + if (count < 2 || count > 3) + throw new ArgumentException("Bad sequence size: " + count, nameof(seq)); + + m_digInfo = DigestInfo.GetInstance(seq[pos++]); + m_salt = Asn1OctetString.GetInstance(seq[pos++]); + m_iterationCount = Asn1Utilities.ReadOptional(seq, ref pos, DerInteger.GetOptional) ?? DerInteger.One; - if (seq.Count == 3) - { - this.iterationCount = ((DerInteger) seq[2]).Value; - } - else - { - this.iterationCount = BigInteger.One; - } + if (pos != count) + throw new ArgumentException("Unexpected elements in sequence", nameof(seq)); } - public MacData( - DigestInfo digInfo, - byte[] salt, - int iterationCount) + public MacData(DigestInfo digInfo, byte[] salt, int iterationCount) { - this.digInfo = digInfo; - this.salt = (byte[]) salt.Clone(); - this.iterationCount = BigInteger.ValueOf(iterationCount); + m_digInfo = digInfo ?? throw new ArgumentNullException(nameof(digInfo)); + m_salt = new DerOctetString(salt); + m_iterationCount = new DerInteger(iterationCount); } - public DigestInfo Mac - { - get { return digInfo; } - } + public DigestInfo Mac => m_digInfo; - public byte[] GetSalt() - { - return (byte[]) salt.Clone(); - } + public byte[] GetSalt() => (byte[])m_salt.GetOctets().Clone(); - public BigInteger IterationCount - { - get { return iterationCount; } - } + public BigInteger IterationCount => m_iterationCount.Value; /** *
@@ -83,14 +66,9 @@ namespace Org.BouncyCastle.Asn1.Pkcs
 		 */
 		public override Asn1Object ToAsn1Object()
         {
-			Asn1EncodableVector v = new Asn1EncodableVector(digInfo, new DerOctetString(salt));
-
-			if (!iterationCount.Equals(BigInteger.One))
-			{
-				v.Add(new DerInteger(iterationCount));
-			}
-
-			return new DerSequence(v);
+            return m_iterationCount.HasValue(1)
+                ?  new DerSequence(m_digInfo, m_salt)
+                :  new DerSequence(m_digInfo, m_salt, m_iterationCount);
         }
     }
 }
diff --git a/crypto/src/asn1/pkcs/PBEParameter.cs b/crypto/src/asn1/pkcs/PBEParameter.cs
index 31d9ad1f3..1fa518e1a 100644
--- a/crypto/src/asn1/pkcs/PBEParameter.cs
+++ b/crypto/src/asn1/pkcs/PBEParameter.cs
@@ -4,12 +4,9 @@ using Org.BouncyCastle.Math;
 
 namespace Org.BouncyCastle.Asn1.Pkcs
 {
-	public class PbeParameter
+    public class PbeParameter
 		: Asn1Encodable
 	{
-		private readonly Asn1OctetString	salt;
-		private readonly DerInteger			iterationCount;
-
         public static PbeParameter GetInstance(object obj)
         {
             if (obj == null)
@@ -19,34 +16,34 @@ namespace Org.BouncyCastle.Asn1.Pkcs
             return new PbeParameter(Asn1Sequence.GetInstance(obj));
         }
 
-		private PbeParameter(Asn1Sequence seq)
+        public static PbeParameter GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new PbeParameter(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
+
+        private readonly Asn1OctetString m_salt;
+        private readonly DerInteger m_iterationCount;
+
+        private PbeParameter(Asn1Sequence seq)
 		{
-			if (seq.Count != 2)
-				throw new ArgumentException("Wrong number of elements in sequence", "seq");
+            int count = seq.Count;
+            if (count != 2)
+                throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
 
-			salt = Asn1OctetString.GetInstance(seq[0]);
-			iterationCount = DerInteger.GetInstance(seq[1]);
+			m_salt = Asn1OctetString.GetInstance(seq[0]);
+			m_iterationCount = DerInteger.GetInstance(seq[1]);
 		}
 
 		public PbeParameter(byte[] salt, int iterationCount)
 		{
-			this.salt = new DerOctetString(salt);
-			this.iterationCount = new DerInteger(iterationCount);
+			m_salt = new DerOctetString(salt);
+			m_iterationCount = new DerInteger(iterationCount);
 		}
 
-		public byte[] GetSalt()
-		{
-			return salt.GetOctets();
-		}
+		public byte[] GetSalt() => m_salt.GetOctets();
 
-		public BigInteger IterationCount
-		{
-			get { return iterationCount.Value; }
-		}
+		public BigInteger IterationCount => m_iterationCount.Value;
 
-		public override Asn1Object ToAsn1Object()
-		{
-			return new DerSequence(salt, iterationCount);
-		}
+		public override Asn1Object ToAsn1Object() => new DerSequence(m_salt, m_iterationCount);
 	}
 }
diff --git a/crypto/src/asn1/pkcs/PBES2Parameters.cs b/crypto/src/asn1/pkcs/PBES2Parameters.cs
index 7d8a91ffa..0741fa8c1 100644
--- a/crypto/src/asn1/pkcs/PBES2Parameters.cs
+++ b/crypto/src/asn1/pkcs/PBES2Parameters.cs
@@ -1,63 +1,51 @@
 using System;
 
+using Org.BouncyCastle.Asn1.X509;
+
 namespace Org.BouncyCastle.Asn1.Pkcs
 {
     public class PbeS2Parameters
         : Asn1Encodable
     {
-        private readonly KeyDerivationFunc func;
-        private readonly EncryptionScheme scheme;
-
         public static PbeS2Parameters GetInstance(object obj)
         {
             if (obj == null)
                 return null;
-            PbeS2Parameters existing = obj as PbeS2Parameters;
-            if (existing != null)
-                return existing;
+            if (obj is PbeS2Parameters pbeS2Parameters)
+                return pbeS2Parameters;
             return new PbeS2Parameters(Asn1Sequence.GetInstance(obj));
         }
 
-        public PbeS2Parameters(KeyDerivationFunc keyDevFunc, EncryptionScheme encScheme)
+        public static PbeS2Parameters GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
         {
-            this.func = keyDevFunc;
-            this.scheme = encScheme;
+            return new PbeS2Parameters(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
         }
 
+        private readonly KeyDerivationFunc m_func;
+        private readonly EncryptionScheme m_scheme;
+
         private PbeS2Parameters(Asn1Sequence seq)
         {
-            if (seq.Count != 2)
-                throw new ArgumentException("Wrong number of elements in sequence", "seq");
-
-            Asn1Sequence funcSeq = (Asn1Sequence)seq[0].ToAsn1Object();
-
-            // TODO Not sure if this special case is really necessary/appropriate
-            if (funcSeq[0].Equals(PkcsObjectIdentifiers.IdPbkdf2))
-            {
-                func = new KeyDerivationFunc(PkcsObjectIdentifiers.IdPbkdf2,
-                    Pbkdf2Params.GetInstance(funcSeq[1]));
-            }
-            else
-            {
-                func = new KeyDerivationFunc(funcSeq);
-            }
-
-            scheme = EncryptionScheme.GetInstance(seq[1]);
-        }
+            int count = seq.Count;
+            if (count != 2)
+                throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
 
-        public KeyDerivationFunc KeyDerivationFunc
-        {
-            get { return func; }
-        }
+            AlgorithmIdentifier func = AlgorithmIdentifier.GetInstance(seq[0]);
+            m_func = new KeyDerivationFunc(func.Algorithm, func.Parameters);
 
-        public EncryptionScheme EncryptionScheme
-        {
-            get { return scheme; }
+            m_scheme = EncryptionScheme.GetInstance(seq[1]);
         }
 
-        public override Asn1Object ToAsn1Object()
+        public PbeS2Parameters(KeyDerivationFunc keyDevFunc, EncryptionScheme encScheme)
         {
-            return new DerSequence(func, scheme);
+            m_func = keyDevFunc ?? throw new ArgumentNullException(nameof(keyDevFunc));
+            m_scheme = encScheme ?? throw new ArgumentNullException(nameof(encScheme));
         }
+
+        public KeyDerivationFunc KeyDerivationFunc => m_func;
+
+        public EncryptionScheme EncryptionScheme => m_scheme;
+
+        public override Asn1Object ToAsn1Object() => new DerSequence(m_func, m_scheme);
     }
 }
diff --git a/crypto/src/asn1/pkcs/PBKDF2Params.cs b/crypto/src/asn1/pkcs/PBKDF2Params.cs
index 13f469c6c..210d673e5 100644
--- a/crypto/src/asn1/pkcs/PBKDF2Params.cs
+++ b/crypto/src/asn1/pkcs/PBKDF2Params.cs
@@ -2,136 +2,98 @@ using System;
 
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Math;
-using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Asn1.Pkcs
 {
     public class Pbkdf2Params
         : Asn1Encodable
     {
-        private static AlgorithmIdentifier algid_hmacWithSHA1 = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdHmacWithSha1, DerNull.Instance);
+        public static readonly AlgorithmIdentifier DefaultPrf = new AlgorithmIdentifier(
+            PkcsObjectIdentifiers.IdHmacWithSha1, DerNull.Instance);
 
-        private readonly Asn1OctetString     octStr;
-        private readonly DerInteger          iterationCount, keyLength;
-        private readonly AlgorithmIdentifier prf;
-
-        public static Pbkdf2Params GetInstance(
-            object obj)
+        public static Pbkdf2Params GetInstance(object obj)
         {
-            if (obj == null || obj is Pbkdf2Params)
-                return (Pbkdf2Params)obj;
-
-            if (obj is Asn1Sequence)
-                return new Pbkdf2Params((Asn1Sequence)obj);
+            if (obj == null)
+                return null;
+            if (obj is Pbkdf2Params pbkdf2Params)
+                return pbkdf2Params;
+#pragma warning disable CS0618 // Type or member is obsolete
+            return new Pbkdf2Params(Asn1Sequence.GetInstance(obj));
+#pragma warning restore CS0618 // Type or member is obsolete
+        }
 
-            throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj");
+        public static Pbkdf2Params GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+#pragma warning disable CS0618 // Type or member is obsolete
+            return new Pbkdf2Params(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+#pragma warning restore CS0618 // Type or member is obsolete
         }
 
-        public Pbkdf2Params(
-            Asn1Sequence seq)
+        private readonly Asn1OctetString m_octStr;
+        private readonly DerInteger m_iterationCount, m_keyLength;
+        private readonly AlgorithmIdentifier m_prf;
+
+        [Obsolete("Use 'GetInstance' instead")]
+        public Pbkdf2Params(Asn1Sequence seq)
         {
-            if (seq.Count < 2 || seq.Count > 4)
-                throw new ArgumentException("Wrong number of elements in sequence", "seq");
+            int count = seq.Count, pos = 0;
+            if (count < 2 || count > 4)
+                throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
 
-            this.octStr = (Asn1OctetString)seq[0];
-            this.iterationCount = (DerInteger)seq[1];
+            m_octStr = Asn1OctetString.GetInstance(seq[pos++]);
+            m_iterationCount = DerInteger.GetInstance(seq[pos++]);
+            m_keyLength = Asn1Utilities.ReadOptional(seq, ref pos, DerInteger.GetOptional);
+            m_prf = Asn1Utilities.ReadOptional(seq, ref pos, AlgorithmIdentifier.GetOptional) ?? DefaultPrf;
 
-            Asn1Encodable kl = null, d = null;
-            if (seq.Count > 3)
-            {
-                kl = seq[2];
-                d = seq[3];
-            }
-            else if (seq.Count > 2)
-            {
-                if (seq[2] is DerInteger)
-                {
-                    kl = seq[2];
-                }
-                else
-                {
-                    d = seq[2];
-                }
-            }
-            if (kl != null)
-            {
-                keyLength = (DerInteger)kl;
-            }
-            if (d != null)
-            {
-                prf = AlgorithmIdentifier.GetInstance(d);
-            }
+            if (pos != count)
+                throw new ArgumentException("Unexpected elements in sequence", nameof(seq));
         }
 
-        public Pbkdf2Params(
-            byte[] salt,
-            int iterationCount)
+        public Pbkdf2Params(byte[] salt, int iterationCount)
+            : this(salt, iterationCount, prf: null)
         {
-            this.octStr = new DerOctetString(salt);
-            this.iterationCount = new DerInteger(iterationCount);
         }
 
-        public Pbkdf2Params(
-            byte[]  salt,
-            int     iterationCount,
-            int     keyLength)
-            : this(salt, iterationCount)
+        public Pbkdf2Params(byte[] salt, int iterationCount, int keyLength)
+            : this(salt, iterationCount, keyLength, prf: null)
         {
-            this.keyLength = new DerInteger(keyLength);
         }
 
-        public Pbkdf2Params(
-            byte[] salt,
-            int iterationCount,
-            int keyLength,
-            AlgorithmIdentifier prf)
-            : this(salt, iterationCount, keyLength)
+        public Pbkdf2Params(byte[] salt, int iterationCount, AlgorithmIdentifier prf)
         {
-            this.prf = prf;
+            m_octStr = new DerOctetString(salt);
+            m_iterationCount = new DerInteger(iterationCount);
+            m_keyLength = null;
+            m_prf = prf ?? DefaultPrf;
         }
 
-        public Pbkdf2Params(
-            byte[] salt,
-            int iterationCount,
-            AlgorithmIdentifier prf)
-            : this(salt, iterationCount)
+        public Pbkdf2Params(byte[] salt, int iterationCount, int keyLength, AlgorithmIdentifier prf)
         {
-            this.prf = prf;
+            m_octStr = new DerOctetString(salt);
+            m_iterationCount = new DerInteger(iterationCount);
+            m_keyLength = new DerInteger(keyLength);
+            m_prf = prf ?? DefaultPrf;
         }
 
-        public byte[] GetSalt()
-        {
-            return octStr.GetOctets();
-        }
+        public byte[] GetSalt() => m_octStr.GetOctets();
 
-        public BigInteger IterationCount
-        {
-            get { return iterationCount.Value; }
-        }
+        public BigInteger IterationCount => m_iterationCount.Value;
 
-        public BigInteger KeyLength
-        {
-            get { return keyLength == null ? null : keyLength.Value; }
-        }
+        public BigInteger KeyLength => m_keyLength?.Value;
 
-        public bool IsDefaultPrf
-        {
-            get { return prf == null || prf.Equals(algid_hmacWithSHA1); }
-        }
+        public bool IsDefaultPrf => DefaultPrf.Equals(m_prf);
 
-        public AlgorithmIdentifier Prf
-        {
-            get { return prf != null ? prf : algid_hmacWithSHA1; }
-        }
+        public AlgorithmIdentifier Prf => m_prf;
 
         public override Asn1Object ToAsn1Object()
         {
-            Asn1EncodableVector v = new Asn1EncodableVector(octStr, iterationCount);
-            v.AddOptional(keyLength);
+            Asn1EncodableVector v = new Asn1EncodableVector(4);
+            v.Add(m_octStr, m_iterationCount);
+            v.AddOptional(m_keyLength);
 
             if (!IsDefaultPrf)
             {
-                v.Add(prf);
+                v.Add(m_prf);
             }
 
             return new DerSequence(v);
diff --git a/crypto/src/asn1/pkcs/PKCS12PBEParams.cs b/crypto/src/asn1/pkcs/PKCS12PBEParams.cs
index b41c289d8..d237d49a2 100644
--- a/crypto/src/asn1/pkcs/PKCS12PBEParams.cs
+++ b/crypto/src/asn1/pkcs/PKCS12PBEParams.cs
@@ -1,63 +1,49 @@
 using System;
 
 using Org.BouncyCastle.Math;
-using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Asn1.Pkcs
 {
     public class Pkcs12PbeParams
         : Asn1Encodable
     {
-        private readonly DerInteger iterations;
-        private readonly Asn1OctetString iv;
-
-		public Pkcs12PbeParams(
-            byte[]	salt,
-            int		iterations)
+        public static Pkcs12PbeParams GetInstance(object obj)
         {
-            this.iv = new DerOctetString(salt);
-            this.iterations = new DerInteger(iterations);
+            if (obj == null)
+                return null;
+            if (obj is Pkcs12PbeParams pkcs12PbeParams)
+                return pkcs12PbeParams;
+            return new Pkcs12PbeParams(Asn1Sequence.GetInstance(obj));
         }
 
-		private Pkcs12PbeParams(
-            Asn1Sequence seq)
+        public static Pkcs12PbeParams GetInstance(Asn1TaggedObject tagged, bool declaredExplicit)
         {
-			if (seq.Count != 2)
-				throw new ArgumentException("Wrong number of elements in sequence", "seq");
-
-			iv = Asn1OctetString.GetInstance(seq[0]);
-            iterations = DerInteger.GetInstance(seq[1]);
+            return new Pkcs12PbeParams(Asn1Sequence.GetInstance(tagged, declaredExplicit));
         }
 
-		public static Pkcs12PbeParams GetInstance(
-            object obj)
-        {
-            if (obj is Pkcs12PbeParams)
-            {
-                return (Pkcs12PbeParams) obj;
-            }
-
-			if (obj is Asn1Sequence)
-            {
-                return new Pkcs12PbeParams((Asn1Sequence) obj);
-            }
-
-			throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj");
-		}
+        private readonly Asn1OctetString m_iv;
+        private readonly DerInteger m_iterations;
 
-		public BigInteger Iterations
-		{
-			get { return iterations.Value; }
-		}
-
-		public byte[] GetIV()
+        private Pkcs12PbeParams(Asn1Sequence seq)
         {
-            return iv.GetOctets();
+            int count = seq.Count;
+            if (count != 2)
+                throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
+
+            m_iv = Asn1OctetString.GetInstance(seq[0]);
+            m_iterations = DerInteger.GetInstance(seq[1]);
         }
 
-		public override Asn1Object ToAsn1Object()
+        public Pkcs12PbeParams(byte[] salt, int iterations)
         {
-			return new DerSequence(iv, iterations);
+            m_iv = new DerOctetString(salt);
+            m_iterations = new DerInteger(iterations);
         }
+
+        public BigInteger Iterations => m_iterations.Value;
+
+        public byte[] GetIV() => m_iv.GetOctets();
+
+        public override Asn1Object ToAsn1Object() => new DerSequence(m_iv, m_iterations);
     }
 }
diff --git a/crypto/src/asn1/pkcs/Pfx.cs b/crypto/src/asn1/pkcs/Pfx.cs
index 67d69a5ae..42ddfbfdd 100644
--- a/crypto/src/asn1/pkcs/Pfx.cs
+++ b/crypto/src/asn1/pkcs/Pfx.cs
@@ -1,8 +1,5 @@
 using System;
 
-using Org.BouncyCastle.Asn1;
-using Org.BouncyCastle.Math;
-
 namespace Org.BouncyCastle.Asn1.Pkcs
 {
     /**
@@ -13,51 +10,51 @@ namespace Org.BouncyCastle.Asn1.Pkcs
     {
         public static Pfx GetInstance(object obj)
         {
-            if (obj is Pfx)
-                return (Pfx)obj;
             if (obj == null)
                 return null;
+            if (obj is Pfx pfx)
+                return pfx;
             return new Pfx(Asn1Sequence.GetInstance(obj));
         }
 
-        private readonly ContentInfo contentInfo;
-        private readonly MacData macData;
+        public static Pfx GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new Pfx(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
+
+        private readonly ContentInfo m_contentInfo;
+        private readonly MacData m_macData;
 
 		private Pfx(Asn1Sequence seq)
         {
+            int count = seq.Count;
+            if (count < 2 || count > 3)
+                throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
+
             DerInteger version = DerInteger.GetInstance(seq[0]);
             if (!version.HasValue(3))
                 throw new ArgumentException("wrong version for PFX PDU");
 
-            this.contentInfo = ContentInfo.GetInstance(seq[1]);
+            m_contentInfo = ContentInfo.GetInstance(seq[1]);
 
-            if (seq.Count == 3)
-            {
-                this.macData = MacData.GetInstance(seq[2]);
-            }
+            m_macData = count <= 2 ? null : MacData.GetInstance(seq[2]);
         }
 
 		public Pfx(ContentInfo contentInfo, MacData macData)
         {
-            this.contentInfo = contentInfo;
-            this.macData = macData;
+            m_contentInfo = contentInfo ?? throw new ArgumentNullException(nameof(contentInfo));
+            m_macData = macData;
         }
 
-		public ContentInfo AuthSafe
-		{
-			get { return contentInfo; }
-		}
+        public ContentInfo AuthSafe => m_contentInfo;
 
-		public MacData MacData
-		{
-			get { return macData; }
-		}
+        public MacData MacData => m_macData;
 
         public override Asn1Object ToAsn1Object()
         {
-            Asn1EncodableVector v = new Asn1EncodableVector(DerInteger.Three, contentInfo);
-            v.AddOptional(macData);
-            return new BerSequence(v);
+            return m_macData == null
+                ?  new BerSequence(DerInteger.Three, m_contentInfo)
+                :  new BerSequence(DerInteger.Three, m_contentInfo, m_macData);
         }
     }
 }
diff --git a/crypto/src/asn1/pkcs/PrivateKeyInfo.cs b/crypto/src/asn1/pkcs/PrivateKeyInfo.cs
index 9535dbcae..7397b7061 100644
--- a/crypto/src/asn1/pkcs/PrivateKeyInfo.cs
+++ b/crypto/src/asn1/pkcs/PrivateKeyInfo.cs
@@ -1,8 +1,6 @@
 using System;
 
 using Org.BouncyCastle.Asn1.X509;
-using Org.BouncyCastle.Math;
-using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.Asn1.Pkcs
 {
@@ -46,166 +44,115 @@ namespace Org.BouncyCastle.Asn1.Pkcs
     public class PrivateKeyInfo
         : Asn1Encodable
     {
-        private readonly DerInteger version;
-        private readonly AlgorithmIdentifier privateKeyAlgorithm;
-        private readonly Asn1OctetString privateKey;
-        private readonly Asn1Set attributes;
-        private readonly DerBitString publicKey;
-
-        public static PrivateKeyInfo GetInstance(Asn1TaggedObject obj, bool explicitly)
-        {
-            return GetInstance(Asn1Sequence.GetInstance(obj, explicitly));
-        }
-
-        public static PrivateKeyInfo GetInstance(
-            object obj)
+        public static PrivateKeyInfo GetInstance(object obj)
         {
             if (obj == null)
                 return null;
-            if (obj is PrivateKeyInfo)
-                return (PrivateKeyInfo)obj;
+            if (obj is PrivateKeyInfo privateKeyInfo)
+                return privateKeyInfo;
             return new PrivateKeyInfo(Asn1Sequence.GetInstance(obj));
         }
 
-        private static int GetVersionValue(DerInteger version)
-        {
-            BigInteger bigValue = version.Value;
-            if (bigValue.CompareTo(BigInteger.Zero) < 0 || bigValue.CompareTo(BigInteger.One) > 0)
-                throw new ArgumentException("invalid version for private key info", "version");
-
-            return bigValue.IntValue;
-        }
-
-        public PrivateKeyInfo(
-            AlgorithmIdentifier privateKeyAlgorithm,
-            Asn1Encodable privateKey)
-            : this(privateKeyAlgorithm, privateKey, null, null)
-        {
-        }
-
-        public PrivateKeyInfo(
-            AlgorithmIdentifier privateKeyAlgorithm,
-            Asn1Encodable privateKey,
-            Asn1Set attributes)
-            : this(privateKeyAlgorithm, privateKey, attributes, null)
+        public static PrivateKeyInfo GetInstance(Asn1TaggedObject obj, bool explicitly)
         {
+            return new PrivateKeyInfo(Asn1Sequence.GetInstance(obj, explicitly));
         }
 
-        public PrivateKeyInfo(
-            AlgorithmIdentifier privateKeyAlgorithm,
-            Asn1Encodable privateKey,
-            Asn1Set attributes,
-            byte[] publicKey)
-        {
-            this.version = new DerInteger(publicKey != null ? BigInteger.One : BigInteger.Zero);
-            this.privateKeyAlgorithm = privateKeyAlgorithm;
-            this.privateKey = new DerOctetString(privateKey);
-            this.attributes = attributes;
-            this.publicKey = publicKey == null ? null : new DerBitString(publicKey);
-        }
+        private readonly DerInteger m_version;
+        private readonly AlgorithmIdentifier m_privateKeyAlgorithm;
+        private readonly Asn1OctetString m_privateKey;
+        private readonly Asn1Set m_attributes;
+        private readonly DerBitString m_publicKey;
 
         private PrivateKeyInfo(Asn1Sequence seq)
         {
-            var e = seq.GetEnumerator();
+            int count = seq.Count, pos = 0;
+            if (count < 3 || count > 5)
+                throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
 
-            this.version = DerInteger.GetInstance(CollectionUtilities.RequireNext(e));
+            m_version = DerInteger.GetInstance(seq[pos++]);
+            m_privateKeyAlgorithm = AlgorithmIdentifier.GetInstance(seq[pos++]);
+            m_privateKey = Asn1OctetString.GetInstance(seq[pos++]);
+            m_attributes = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 0, false, Asn1Set.GetInstance);
+            m_publicKey = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 1, false, DerBitString.GetInstance);
 
-            int versionValue = GetVersionValue(version);
+            if (pos != count)
+                throw new ArgumentException("Unexpected elements in sequence", nameof(seq));
 
-            this.privateKeyAlgorithm = AlgorithmIdentifier.GetInstance(CollectionUtilities.RequireNext(e));
-            this.privateKey = Asn1OctetString.GetInstance(CollectionUtilities.RequireNext(e));
+            int versionValue = GetVersionValue(m_version);
 
-            int lastTag = -1;
-            while (e.MoveNext())
-            {
-                Asn1TaggedObject tagged = (Asn1TaggedObject)e.Current;
-
-                int tag = tagged.TagNo;
-                if (tag <= lastTag)
-                    throw new ArgumentException("invalid optional field in private key info", "seq");
-
-                lastTag = tag;
-
-                switch (tag)
-                {
-                case 0:
-                {
-                    this.attributes = Asn1Set.GetInstance(tagged, false);
-                    break;
-                }
-                case 1:
-                {
-                    if (versionValue < 1)
-                        throw new ArgumentException("'publicKey' requires version v2(1) or later", "seq");
-
-                    this.publicKey = DerBitString.GetInstance(tagged, false);
-                    break;
-                }
-                default:
-                {
-                    throw new ArgumentException("unknown optional field in private key info", "seq");
-                }
-                }
-            }
+            if (m_publicKey != null && versionValue < 1)
+                throw new ArgumentException("'publicKey' requires version v2(1) or later", nameof(seq));
         }
 
-        public virtual DerInteger Version
+        public PrivateKeyInfo(AlgorithmIdentifier privateKeyAlgorithm, Asn1Encodable privateKey)
+            : this(privateKeyAlgorithm, privateKey, null, null)
         {
-            get { return version; }
         }
 
-        public virtual Asn1Set Attributes
+        public PrivateKeyInfo(AlgorithmIdentifier privateKeyAlgorithm, Asn1Encodable privateKey, Asn1Set attributes)
+            : this(privateKeyAlgorithm, privateKey, attributes, null)
         {
-            get { return attributes; }
         }
 
-        /// Return true if a public key is present, false otherwise.
-        public virtual bool HasPublicKey
+        public PrivateKeyInfo(AlgorithmIdentifier privateKeyAlgorithm, Asn1Encodable privateKey, Asn1Set attributes,
+            byte[] publicKey)
         {
-            get { return publicKey != null; }
+            m_version = new DerInteger(publicKey != null ? 1 : 0);
+            m_privateKeyAlgorithm = privateKeyAlgorithm ?? throw new ArgumentNullException(nameof(privateKeyAlgorithm));
+            m_privateKey = new DerOctetString(privateKey);
+            m_attributes = attributes;
+            m_publicKey = publicKey == null ? null : new DerBitString(publicKey);
         }
 
-        public virtual AlgorithmIdentifier PrivateKeyAlgorithm
-        {
-            get { return privateKeyAlgorithm; }
-        }
+        public virtual DerInteger Version => m_version;
 
-        public virtual Asn1OctetString PrivateKey => privateKey;
+        public virtual Asn1Set Attributes => m_attributes;
+
+        /// Return true if a public key is present, false otherwise.
+        public virtual bool HasPublicKey => m_publicKey != null;
+
+        public virtual AlgorithmIdentifier PrivateKeyAlgorithm => m_privateKeyAlgorithm;
+
+        public virtual Asn1OctetString PrivateKey => m_privateKey;
 
         [Obsolete("Use 'PrivateKey' instead")]
-        public virtual Asn1OctetString PrivateKeyData
-        {
-            get { return privateKey; }
-        }
+        public virtual Asn1OctetString PrivateKeyData => m_privateKey;
 
-        public virtual int PrivateKeyLength => privateKey.GetOctetsLength();
+        public virtual int PrivateKeyLength => m_privateKey.GetOctetsLength();
 
-        public virtual Asn1Object ParsePrivateKey()
-        {
-            return Asn1Object.FromByteArray(privateKey.GetOctets());
-        }
+        public virtual Asn1Object ParsePrivateKey() => Asn1Object.FromByteArray(m_privateKey.GetOctets());
 
         /// For when the public key is an ASN.1 encoding.
         public virtual Asn1Object ParsePublicKey()
         {
-            return publicKey == null ? null : Asn1Object.FromByteArray(publicKey.GetOctets());
+            return m_publicKey == null ? null : Asn1Object.FromByteArray(m_publicKey.GetOctets());
         }
 
-        public virtual DerBitString PublicKey => publicKey;
+        public virtual DerBitString PublicKey => m_publicKey;
 
         /// Return the public key as a raw bit string.
         [Obsolete("Use 'PublicKey' instead")]
-        public virtual DerBitString PublicKeyData
-        {
-            get { return publicKey; }
-        }
+        public virtual DerBitString PublicKeyData => m_publicKey;
 
         public override Asn1Object ToAsn1Object()
         {
-            Asn1EncodableVector v = new Asn1EncodableVector(version, privateKeyAlgorithm, privateKey);
-            v.AddOptionalTagged(false, 0, attributes);
-            v.AddOptionalTagged(false, 1, publicKey);
+            Asn1EncodableVector v = new Asn1EncodableVector(5);
+            v.Add(m_version, m_privateKeyAlgorithm, m_privateKey);
+            v.AddOptionalTagged(false, 0, m_attributes);
+            v.AddOptionalTagged(false, 1, m_publicKey);
             return new DerSequence(v);
         }
+
+        private static int GetVersionValue(DerInteger version)
+        {
+            if (version.TryGetIntPositiveValueExact(out int value))
+            {
+                if (value >= 0 && value <= 1)
+                    return value;
+            }
+
+            throw new ArgumentException("Invalid version for PrivateKeyInfo", nameof(version));
+        }
     }
 }
diff --git a/crypto/src/asn1/pkcs/RC2CBCParameter.cs b/crypto/src/asn1/pkcs/RC2CBCParameter.cs
index c1f09a088..f38695f50 100644
--- a/crypto/src/asn1/pkcs/RC2CBCParameter.cs
+++ b/crypto/src/asn1/pkcs/RC2CBCParameter.cs
@@ -8,67 +8,56 @@ namespace Org.BouncyCastle.Asn1.Pkcs
     public class RC2CbcParameter
         : Asn1Encodable
     {
-        internal DerInteger			version;
-        internal Asn1OctetString	iv;
-
-		public static RC2CbcParameter GetInstance(
-            object obj)
+		public static RC2CbcParameter GetInstance(object obj)
         {
-            if (obj is Asn1Sequence)
-            {
-                return new RC2CbcParameter((Asn1Sequence) obj);
-            }
-
-			throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj");
+            if (obj == null)
+                return null;
+            if (obj is RC2CbcParameter rc2CbcParameter)
+                return rc2CbcParameter;
+            return new RC2CbcParameter(Asn1Sequence.GetInstance(obj));
 		}
 
-		public RC2CbcParameter(
-            byte[] iv)
-        {
-            this.iv = new DerOctetString(iv);
-        }
+        private readonly DerInteger m_version;
+        private readonly Asn1OctetString m_iv;
 
-		public RC2CbcParameter(
-            int		parameterVersion,
-            byte[]	iv)
+        private RC2CbcParameter(Asn1Sequence seq)
         {
-            this.version = new DerInteger(parameterVersion);
-            this.iv = new DerOctetString(iv);
-        }
+            int count = seq.Count, pos = 0;
+            if (count < 1 || count > 2)
+                throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
 
-		private RC2CbcParameter(
-            Asn1Sequence seq)
-        {
-            if (seq.Count == 1)
-            {
-                iv = (Asn1OctetString)seq[0];
-            }
-            else
-            {
-                version = (DerInteger)seq[0];
-                iv = (Asn1OctetString)seq[1];
-            }
+            m_version = Asn1Utilities.ReadOptional(seq, ref pos, DerInteger.GetOptional);
+            m_iv = Asn1OctetString.GetInstance(seq[pos++]);
+
+            if (pos != count)
+                throw new ArgumentException("Unexpected elements in sequence", nameof(seq));
         }
 
-		public BigInteger RC2ParameterVersion
+        public RC2CbcParameter(byte[] iv)
         {
-            get
-            {
-				return version == null ? null : version.Value;
-            }
+            m_version = null;
+            m_iv = new DerOctetString(iv);
         }
 
-		public byte[] GetIV()
+		public RC2CbcParameter(int parameterVersion, byte[] iv)
         {
-			return Arrays.Clone(iv.GetOctets());
+            m_version = new DerInteger(parameterVersion);
+            m_iv = new DerOctetString(iv);
         }
 
+        public BigInteger RC2ParameterVersion => m_version?.Value;
+
+        public DerInteger RC2ParameterVersionData => m_version;
+
+        public Asn1OctetString IV => m_iv;
+
+        public byte[] GetIV() => Arrays.Clone(m_iv.GetOctets());
+
         public override Asn1Object ToAsn1Object()
         {
-            Asn1EncodableVector v = new Asn1EncodableVector(2);
-            v.AddOptional(version);
-            v.Add(iv);
-            return new DerSequence(v);
+            return m_version == null
+                ?  new DerSequence(m_iv)
+                :  new DerSequence(m_version, m_iv);
         }
     }
 }
diff --git a/crypto/src/asn1/pkcs/RSAESOAEPparams.cs b/crypto/src/asn1/pkcs/RSAESOAEPparams.cs
index 988b230c8..3490509e7 100644
--- a/crypto/src/asn1/pkcs/RSAESOAEPparams.cs
+++ b/crypto/src/asn1/pkcs/RSAESOAEPparams.cs
@@ -2,103 +2,86 @@ using System;
 
 using Org.BouncyCastle.Asn1.Oiw;
 using Org.BouncyCastle.Asn1.X509;
-using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Asn1.Pkcs
 {
-	public class RsaesOaepParameters
+    public class RsaesOaepParameters
 		: Asn1Encodable
 	{
-		private AlgorithmIdentifier hashAlgorithm;
-		private AlgorithmIdentifier maskGenAlgorithm;
-		private AlgorithmIdentifier pSourceAlgorithm;
-
-		public readonly static AlgorithmIdentifier DefaultHashAlgorithm = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance);
-		public readonly static AlgorithmIdentifier DefaultMaskGenFunction = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, DefaultHashAlgorithm);
-		public readonly static AlgorithmIdentifier DefaultPSourceAlgorithm = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdPSpecified, new DerOctetString(new byte[0]));
-
-		public static RsaesOaepParameters GetInstance(
-			object obj)
-		{
-			if (obj is RsaesOaepParameters)
-			{
-				return (RsaesOaepParameters)obj;
-			}
-			else if (obj is Asn1Sequence)
-			{
-				return new RsaesOaepParameters((Asn1Sequence)obj);
-			}
-
-			throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj");
-		}
-
-		/**
+		public static readonly AlgorithmIdentifier DefaultHashAlgorithm = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance);
+		public static readonly AlgorithmIdentifier DefaultMaskGenAlgorithm = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, DefaultHashAlgorithm);
+        [Obsolete("Use 'DefaultMaskGenAlgorithm' instead")]
+        public static readonly AlgorithmIdentifier DefaultMaskGenFunction = DefaultMaskGenAlgorithm;
+        public static readonly AlgorithmIdentifier DefaultPSourceAlgorithm = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdPSpecified, new DerOctetString(new byte[0]));
+
+        public static RsaesOaepParameters GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is RsaesOaepParameters rsaesOaepParameters)
+                return rsaesOaepParameters;
+#pragma warning disable CS0618 // Type or member is obsolete
+            return new RsaesOaepParameters(Asn1Sequence.GetInstance(obj));
+#pragma warning restore CS0618 // Type or member is obsolete
+        }
+
+        public static RsaesOaepParameters GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+#pragma warning disable CS0618 // Type or member is obsolete
+            return new RsaesOaepParameters(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+#pragma warning restore CS0618 // Type or member is obsolete
+        }
+
+        private readonly AlgorithmIdentifier m_hashAlgorithm;
+        private readonly AlgorithmIdentifier m_maskGenAlgorithm;
+        private readonly AlgorithmIdentifier m_pSourceAlgorithm;
+
+        [Obsolete("Use 'GetInstance' instead")]
+        public RsaesOaepParameters(Asn1Sequence seq)
+        {
+            int count = seq.Count, pos = 0;
+            if (count < 0 || count > 3)
+                throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
+
+			m_hashAlgorithm = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 0, true, AlgorithmIdentifier.GetInstance)
+				?? DefaultHashAlgorithm;
+
+            m_maskGenAlgorithm = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 1, true, AlgorithmIdentifier.GetInstance)
+                ?? DefaultMaskGenAlgorithm;
+
+            m_pSourceAlgorithm = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 2, true, AlgorithmIdentifier.GetInstance)
+                ?? DefaultPSourceAlgorithm;
+
+            if (pos != count)
+                throw new ArgumentException("Unexpected elements in sequence", nameof(seq));
+        }
+
+        /**
 		 * The default version
 		 */
-		public RsaesOaepParameters()
-		    : this(DefaultHashAlgorithm, DefaultMaskGenFunction, DefaultPSourceAlgorithm)
+        public RsaesOaepParameters()
+		    : this(DefaultHashAlgorithm, DefaultMaskGenAlgorithm, DefaultPSourceAlgorithm)
 		{ 
 		}
 
-		public RsaesOaepParameters(
-			AlgorithmIdentifier hashAlgorithm,
-			AlgorithmIdentifier maskGenAlgorithm)
-		    : this(hashAlgorithm, maskGenAlgorithm, DefaultPSourceAlgorithm)
-		{
-		}
+        public RsaesOaepParameters(AlgorithmIdentifier hashAlgorithm, AlgorithmIdentifier maskGenAlgorithm)
+            : this(hashAlgorithm, maskGenAlgorithm, DefaultPSourceAlgorithm)
+        {
+        }
 
-		public RsaesOaepParameters(
-			AlgorithmIdentifier hashAlgorithm,
-			AlgorithmIdentifier maskGenAlgorithm,
-			AlgorithmIdentifier pSourceAlgorithm)
-		{
-			this.hashAlgorithm = hashAlgorithm;
-			this.maskGenAlgorithm = maskGenAlgorithm;
-			this.pSourceAlgorithm = pSourceAlgorithm;
-		}
+        public RsaesOaepParameters(AlgorithmIdentifier hashAlgorithm, AlgorithmIdentifier maskGenAlgorithm,
+            AlgorithmIdentifier pSourceAlgorithm)
+        {
+            m_hashAlgorithm = hashAlgorithm;
+            m_maskGenAlgorithm = maskGenAlgorithm;
+            m_pSourceAlgorithm = pSourceAlgorithm;
+        }
 
-		public RsaesOaepParameters(
-			Asn1Sequence seq)
-		{
-			hashAlgorithm = DefaultHashAlgorithm;
-			maskGenAlgorithm = DefaultMaskGenFunction;
-			pSourceAlgorithm = DefaultPSourceAlgorithm;
+		public AlgorithmIdentifier HashAlgorithm => m_hashAlgorithm;
 
-			for (int i = 0; i != seq.Count; i++)
-			{
-				Asn1TaggedObject o = (Asn1TaggedObject)seq[i];
-
-				switch (o.TagNo)
-				{
-					case 0:
-						hashAlgorithm = AlgorithmIdentifier.GetInstance(o, true);
-						break;
-					case 1:
-						maskGenAlgorithm = AlgorithmIdentifier.GetInstance(o, true);
-						break;
-					case 2:
-						pSourceAlgorithm = AlgorithmIdentifier.GetInstance(o, true);
-						break;
-					default:
-						throw new ArgumentException("unknown tag");
-				}
-			}
-		}
+		public AlgorithmIdentifier MaskGenAlgorithm => m_maskGenAlgorithm;
 
-		public AlgorithmIdentifier HashAlgorithm
-		{
-			get { return hashAlgorithm; }
-		}
-
-		public AlgorithmIdentifier MaskGenAlgorithm
-		{
-			get { return maskGenAlgorithm; }
-		}
-
-		public AlgorithmIdentifier PSourceAlgorithm
-		{
-			get { return pSourceAlgorithm; }
-		}
+		public AlgorithmIdentifier PSourceAlgorithm => m_pSourceAlgorithm;
 
 		/**
 		 * 
@@ -130,19 +113,19 @@ namespace Org.BouncyCastle.Asn1.Pkcs
 		{
 			Asn1EncodableVector v = new Asn1EncodableVector(3);
 
-			if (!hashAlgorithm.Equals(DefaultHashAlgorithm))
+			if (!DefaultHashAlgorithm.Equals(m_hashAlgorithm))
 			{
-				v.Add(new DerTaggedObject(true, 0, hashAlgorithm));
+				v.Add(new DerTaggedObject(true, 0, m_hashAlgorithm));
 			}
 
-			if (!maskGenAlgorithm.Equals(DefaultMaskGenFunction))
+			if (!DefaultMaskGenAlgorithm.Equals(m_maskGenAlgorithm))
 			{
-				v.Add(new DerTaggedObject(true, 1, maskGenAlgorithm));
+				v.Add(new DerTaggedObject(true, 1, m_maskGenAlgorithm));
 			}
 
-			if (!pSourceAlgorithm.Equals(DefaultPSourceAlgorithm))
+			if (!DefaultPSourceAlgorithm.Equals(m_pSourceAlgorithm))
 			{
-				v.Add(new DerTaggedObject(true, 2, pSourceAlgorithm));
+				v.Add(new DerTaggedObject(true, 2, m_pSourceAlgorithm));
 			}
 
 			return new DerSequence(v);
diff --git a/crypto/src/asn1/pkcs/RSAPrivateKeyStructure.cs b/crypto/src/asn1/pkcs/RSAPrivateKeyStructure.cs
index 0e7911163..afd642255 100644
--- a/crypto/src/asn1/pkcs/RSAPrivateKeyStructure.cs
+++ b/crypto/src/asn1/pkcs/RSAPrivateKeyStructure.cs
@@ -7,29 +7,29 @@ namespace Org.BouncyCastle.Asn1.Pkcs
     public class RsaPrivateKeyStructure
         : Asn1Encodable
     {
-        private readonly BigInteger modulus;
-        private readonly BigInteger publicExponent;
-        private readonly BigInteger privateExponent;
-        private readonly BigInteger prime1;
-        private readonly BigInteger prime2;
-        private readonly BigInteger exponent1;
-        private readonly BigInteger exponent2;
-        private readonly BigInteger coefficient;
-
-        public static RsaPrivateKeyStructure GetInstance(Asn1TaggedObject obj, bool isExplicit)
-        {
-            return GetInstance(Asn1Sequence.GetInstance(obj, isExplicit));
-        }
-
         public static RsaPrivateKeyStructure GetInstance(object obj)
         {
             if (obj == null)
                 return null;
-            if (obj is RsaPrivateKeyStructure)
-                return (RsaPrivateKeyStructure)obj;
+            if (obj is RsaPrivateKeyStructure rsaPrivateKeyStructure)
+                return rsaPrivateKeyStructure;
             return new RsaPrivateKeyStructure(Asn1Sequence.GetInstance(obj));
         }
 
+        public static RsaPrivateKeyStructure GetInstance(Asn1TaggedObject obj, bool isExplicit)
+        {
+            return new RsaPrivateKeyStructure(Asn1Sequence.GetInstance(obj, isExplicit));
+        }
+
+        private readonly BigInteger m_modulus;
+        private readonly BigInteger m_publicExponent;
+        private readonly BigInteger m_privateExponent;
+        private readonly BigInteger m_prime1;
+        private readonly BigInteger m_prime2;
+        private readonly BigInteger m_exponent1;
+        private readonly BigInteger m_exponent2;
+        private readonly BigInteger m_coefficient;
+
         public RsaPrivateKeyStructure(
             BigInteger modulus,
             BigInteger publicExponent,
@@ -40,71 +40,51 @@ namespace Org.BouncyCastle.Asn1.Pkcs
             BigInteger exponent2,
             BigInteger coefficient)
         {
-            this.modulus = modulus;
-            this.publicExponent = publicExponent;
-            this.privateExponent = privateExponent;
-            this.prime1 = prime1;
-            this.prime2 = prime2;
-            this.exponent1 = exponent1;
-            this.exponent2 = exponent2;
-            this.coefficient = coefficient;
+            m_modulus = modulus ?? throw new ArgumentNullException(nameof(modulus));
+            m_publicExponent = publicExponent ?? throw new ArgumentNullException(nameof(publicExponent));
+            m_privateExponent = privateExponent ?? throw new ArgumentNullException(nameof(privateExponent));
+            m_prime1 = prime1 ?? throw new ArgumentNullException(nameof(prime1));
+            m_prime2 = prime2 ?? throw new ArgumentNullException(nameof(prime2));
+            m_exponent1 = exponent1 ?? throw new ArgumentNullException(nameof(exponent1));
+            m_exponent2 = exponent2 ?? throw new ArgumentNullException(nameof(exponent2));
+            m_coefficient = coefficient ?? throw new ArgumentNullException(nameof(coefficient));
         }
 
         private RsaPrivateKeyStructure(Asn1Sequence seq)
         {
-            BigInteger version = ((DerInteger)seq[0]).Value;
-            if (version.IntValue != 0)
+            int count = seq.Count;
+            if (count != 9)
+                throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
+
+            var version = DerInteger.GetInstance(seq[0]);
+            m_modulus = DerInteger.GetInstance(seq[1]).Value;
+            m_publicExponent = DerInteger.GetInstance(seq[2]).Value;
+            m_privateExponent = DerInteger.GetInstance(seq[3]).Value;
+            m_prime1 = DerInteger.GetInstance(seq[4]).Value;
+            m_prime2 = DerInteger.GetInstance(seq[5]).Value;
+            m_exponent1 = DerInteger.GetInstance(seq[6]).Value;
+            m_exponent2 = DerInteger.GetInstance(seq[7]).Value;
+            m_coefficient = DerInteger.GetInstance(seq[8]).Value;
+
+            if (!version.HasValue(0))
                 throw new ArgumentException("wrong version for RSA private key");
-
-            modulus = ((DerInteger)seq[1]).Value;
-            publicExponent = ((DerInteger)seq[2]).Value;
-            privateExponent = ((DerInteger)seq[3]).Value;
-            prime1 = ((DerInteger)seq[4]).Value;
-            prime2 = ((DerInteger)seq[5]).Value;
-            exponent1 = ((DerInteger)seq[6]).Value;
-            exponent2 = ((DerInteger)seq[7]).Value;
-            coefficient = ((DerInteger)seq[8]).Value;
         }
 
-        public BigInteger Modulus
-        {
-            get { return modulus; }
-        }
+        public BigInteger Modulus => m_modulus;
 
-        public BigInteger PublicExponent
-        {
-            get { return publicExponent; }
-        }
+        public BigInteger PublicExponent => m_publicExponent;
 
-        public BigInteger PrivateExponent
-        {
-            get { return privateExponent; }
-        }
+        public BigInteger PrivateExponent => m_privateExponent;
 
-        public BigInteger Prime1
-        {
-            get { return prime1; }
-        }
+        public BigInteger Prime1 => m_prime1;
 
-        public BigInteger Prime2
-        {
-            get { return prime2; }
-        }
+        public BigInteger Prime2 => m_prime2;
 
-        public BigInteger Exponent1
-        {
-            get { return exponent1; }
-        }
+        public BigInteger Exponent1 => m_exponent1;
 
-        public BigInteger Exponent2
-        {
-            get { return exponent2; }
-        }
+        public BigInteger Exponent2 => m_exponent2;
 
-        public BigInteger Coefficient
-        {
-            get { return coefficient; }
-        }
+        public BigInteger Coefficient => m_coefficient;
 
         /**
          * This outputs the key in Pkcs1v2 format.
@@ -129,14 +109,14 @@ namespace Org.BouncyCastle.Asn1.Pkcs
         {
             return new DerSequence(
                 DerInteger.Zero, // version
-                new DerInteger(Modulus),
-                new DerInteger(PublicExponent),
-                new DerInteger(PrivateExponent),
-                new DerInteger(Prime1),
-                new DerInteger(Prime2),
-                new DerInteger(Exponent1),
-                new DerInteger(Exponent2),
-                new DerInteger(Coefficient));
+                new DerInteger(m_modulus),
+                new DerInteger(m_publicExponent),
+                new DerInteger(m_privateExponent),
+                new DerInteger(m_prime1),
+                new DerInteger(m_prime2),
+                new DerInteger(m_exponent1),
+                new DerInteger(m_exponent2),
+                new DerInteger(m_coefficient));
         }
     }
 }
diff --git a/crypto/src/asn1/pkcs/RSASSAPSSparams.cs b/crypto/src/asn1/pkcs/RSASSAPSSparams.cs
index ead2faa73..f7a9d6956 100644
--- a/crypto/src/asn1/pkcs/RSASSAPSSparams.cs
+++ b/crypto/src/asn1/pkcs/RSASSAPSSparams.cs
@@ -2,113 +2,92 @@ using System;
 
 using Org.BouncyCastle.Asn1.Oiw;
 using Org.BouncyCastle.Asn1.X509;
-using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Asn1.Pkcs
 {
-	public class RsassaPssParameters
+    public class RsassaPssParameters
 		: Asn1Encodable
 	{
-		private AlgorithmIdentifier hashAlgorithm;
-		private AlgorithmIdentifier maskGenAlgorithm;
-		private DerInteger saltLength;
-		private DerInteger trailerField;
-
 		public readonly static AlgorithmIdentifier DefaultHashAlgorithm = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance);
-		public readonly static AlgorithmIdentifier DefaultMaskGenFunction = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, DefaultHashAlgorithm);
+        public readonly static AlgorithmIdentifier DefaultMaskGenAlgorithm = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, DefaultHashAlgorithm);
+        [Obsolete("Use 'DefaultMaskGenAlgorithm' instead")]
+        public readonly static AlgorithmIdentifier DefaultMaskGenFunction = DefaultMaskGenAlgorithm;
 		public readonly static DerInteger DefaultSaltLength = new DerInteger(20);
 		public readonly static DerInteger DefaultTrailerField = DerInteger.One;
 
-		public static RsassaPssParameters GetInstance(
-			object obj)
+        public static RsassaPssParameters GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is RsassaPssParameters rsassaPssParameters)
+                return rsassaPssParameters;
+#pragma warning disable CS0618 // Type or member is obsolete
+            return new RsassaPssParameters(Asn1Sequence.GetInstance(obj));
+#pragma warning restore CS0618 // Type or member is obsolete
+        }
+
+        public static RsassaPssParameters GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+#pragma warning disable CS0618 // Type or member is obsolete
+            return new RsassaPssParameters(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+#pragma warning restore CS0618 // Type or member is obsolete
+        }
+
+        private readonly AlgorithmIdentifier m_hashAlgorithm;
+        private readonly AlgorithmIdentifier m_maskGenAlgorithm;
+        private readonly DerInteger m_saltLength;
+        private readonly DerInteger m_trailerField;
+
+        [Obsolete("Use 'GetInstance' instead")]
+        public RsassaPssParameters(Asn1Sequence seq)
 		{
-			if (obj == null || obj is RsassaPssParameters)
-			{
-				return (RsassaPssParameters)obj;
-			}
+            int count = seq.Count, pos = 0;
+            if (count < 0 || count > 4)
+                throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
 
-			if (obj is Asn1Sequence)
-			{
-				return new RsassaPssParameters((Asn1Sequence)obj);
-			}
+            m_hashAlgorithm = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 0, true, AlgorithmIdentifier.GetInstance)
+                ?? DefaultHashAlgorithm;
 
-			throw new ArgumentException("Unknown object in factory: " + Platform.GetTypeName(obj), "obj");
-		}
+            m_maskGenAlgorithm = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 1, true, AlgorithmIdentifier.GetInstance)
+                ?? DefaultMaskGenAlgorithm;
 
-		/**
-		 * The default version
-		 */
-		public RsassaPssParameters()
-		{
-			hashAlgorithm = DefaultHashAlgorithm;
-			maskGenAlgorithm = DefaultMaskGenFunction;
-			saltLength = DefaultSaltLength;
-			trailerField = DefaultTrailerField;
-		}
+            m_saltLength = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 2, true, DerInteger.GetInstance)
+                ?? DefaultSaltLength;
 
-		public RsassaPssParameters(
-			AlgorithmIdentifier hashAlgorithm,
-			AlgorithmIdentifier maskGenAlgorithm,
-			DerInteger saltLength,
-			DerInteger trailerField)
-		{
-			this.hashAlgorithm = hashAlgorithm;
-			this.maskGenAlgorithm = maskGenAlgorithm;
-			this.saltLength = saltLength;
-			this.trailerField = trailerField;
+            m_trailerField = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 3, true, DerInteger.GetInstance)
+                ?? DefaultTrailerField;
+
+            if (pos != count)
+                throw new ArgumentException("Unexpected elements in sequence", nameof(seq));
 		}
 
-		public RsassaPssParameters(
-			Asn1Sequence seq)
-		{
-			hashAlgorithm = DefaultHashAlgorithm;
-			maskGenAlgorithm = DefaultMaskGenFunction;
-			saltLength = DefaultSaltLength;
-			trailerField = DefaultTrailerField;
+        /**
+		 * The default version
+		 */
+        public RsassaPssParameters()
+        {
+            m_hashAlgorithm = DefaultHashAlgorithm;
+            m_maskGenAlgorithm = DefaultMaskGenAlgorithm;
+            m_saltLength = DefaultSaltLength;
+            m_trailerField = DefaultTrailerField;
+        }
 
-			for (int i = 0; i != seq.Count; i++)
-			{
-				Asn1TaggedObject o = (Asn1TaggedObject)seq[i];
-
-				switch (o.TagNo)
-				{
-					case 0:
-						hashAlgorithm = AlgorithmIdentifier.GetInstance(o, true);
-						break;
-					case 1:
-						maskGenAlgorithm = AlgorithmIdentifier.GetInstance(o, true);
-						break;
-					case 2:
-						saltLength = DerInteger.GetInstance(o, true);
-						break;
-					case 3:
-						trailerField = DerInteger.GetInstance(o, true);
-						break;
-					default:
-						throw new ArgumentException("unknown tag");
-				}
-			}
-		}
+        public RsassaPssParameters(AlgorithmIdentifier hashAlgorithm, AlgorithmIdentifier maskGenAlgorithm,
+            DerInteger saltLength, DerInteger trailerField)
+        {
+            m_hashAlgorithm = hashAlgorithm ?? DefaultHashAlgorithm;
+            m_maskGenAlgorithm = maskGenAlgorithm ?? DefaultMaskGenAlgorithm;
+            m_saltLength = saltLength ?? DefaultSaltLength;
+            m_trailerField = trailerField ?? DefaultTrailerField;
+        }
 
-		public AlgorithmIdentifier HashAlgorithm
-		{
-			get { return hashAlgorithm; }
-		}
+		public AlgorithmIdentifier HashAlgorithm => m_hashAlgorithm;
 
-		public AlgorithmIdentifier MaskGenAlgorithm
-		{
-			get { return maskGenAlgorithm; }
-		}
+		public AlgorithmIdentifier MaskGenAlgorithm => m_maskGenAlgorithm;
 
-		public DerInteger SaltLength
-		{
-			get { return saltLength; }
-		}
+		public DerInteger SaltLength => m_saltLength;
 
-		public DerInteger TrailerField
-		{
-			get { return trailerField; }
-		}
+		public DerInteger TrailerField => m_trailerField;
 
 		/**
 		 * 
@@ -140,24 +119,24 @@ namespace Org.BouncyCastle.Asn1.Pkcs
 		{
 			Asn1EncodableVector v = new Asn1EncodableVector(4);
 
-			if (!hashAlgorithm.Equals(DefaultHashAlgorithm))
+			if (!DefaultHashAlgorithm.Equals(m_hashAlgorithm))
 			{
-				v.Add(new DerTaggedObject(true, 0, hashAlgorithm));
+				v.Add(new DerTaggedObject(true, 0, m_hashAlgorithm));
 			}
 
-			if (!maskGenAlgorithm.Equals(DefaultMaskGenFunction))
+			if (!DefaultMaskGenAlgorithm.Equals(m_maskGenAlgorithm))
 			{
-				v.Add(new DerTaggedObject(true, 1, maskGenAlgorithm));
+				v.Add(new DerTaggedObject(true, 1, m_maskGenAlgorithm));
 			}
 
-			if (!saltLength.Equals(DefaultSaltLength))
+			if (!DefaultSaltLength.Equals(m_saltLength))
 			{
-				v.Add(new DerTaggedObject(true, 2, saltLength));
+				v.Add(new DerTaggedObject(true, 2, m_saltLength));
 			}
 
-			if (!trailerField.Equals(DefaultTrailerField))
+			if (!DefaultTrailerField.Equals(m_trailerField))
 			{
-				v.Add(new DerTaggedObject(true, 3, trailerField));
+				v.Add(new DerTaggedObject(true, 3, m_trailerField));
 			}
 
 			return new DerSequence(v);
diff --git a/crypto/src/asn1/pkcs/SafeBag.cs b/crypto/src/asn1/pkcs/SafeBag.cs
index 8b35a6717..9f8dbb8cc 100644
--- a/crypto/src/asn1/pkcs/SafeBag.cs
+++ b/crypto/src/asn1/pkcs/SafeBag.cs
@@ -1,7 +1,5 @@
 using System;
 
-using Org.BouncyCastle.Asn1;
-
 namespace Org.BouncyCastle.Asn1.Pkcs
 {
     public class SafeBag
@@ -9,65 +7,60 @@ namespace Org.BouncyCastle.Asn1.Pkcs
     {
         public static SafeBag GetInstance(object obj)
         {
-            if (obj is SafeBag)
-                return (SafeBag)obj;
             if (obj == null)
                 return null;
+            if (obj is SafeBag safeBag)
+                return safeBag;
             return new SafeBag(Asn1Sequence.GetInstance(obj));
         }
 
-        private readonly DerObjectIdentifier bagID;
-        private readonly Asn1Object bagValue;
-        private readonly Asn1Set bagAttributes;
+        public static SafeBag GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+            return new SafeBag(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+        }
+
+        private readonly DerObjectIdentifier m_bagID;
+        private readonly Asn1Object m_bagValue;
+        private readonly Asn1Set m_bagAttributes;
 
-		public SafeBag(
-            DerObjectIdentifier	oid,
-            Asn1Object			obj)
+        private SafeBag(Asn1Sequence seq)
         {
-            this.bagID = oid;
-            this.bagValue = obj;
-            this.bagAttributes = null;
+            int count = seq.Count, pos = 0;
+            if (count < 2 || count > 3)
+                throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
+
+            m_bagID = DerObjectIdentifier.GetInstance(seq[pos++]);
+            m_bagValue = Asn1TaggedObject.GetInstance(seq[pos++], Asn1Tags.ContextSpecific, 0)
+                .GetExplicitBaseObject().ToAsn1Object();
+            m_bagAttributes = Asn1Utilities.ReadOptional(seq, ref pos, Asn1Set.GetOptional);
+
+            if (pos != count)
+                throw new ArgumentException("Unexpected elements in sequence", nameof(seq));
         }
 
-		public SafeBag(
-            DerObjectIdentifier	oid,
-            Asn1Object			obj,
-            Asn1Set				bagAttributes)
+        public SafeBag(DerObjectIdentifier oid, Asn1Object obj)
+            : this(oid, obj, null)
         {
-            this.bagID = oid;
-            this.bagValue = obj;
-            this.bagAttributes = bagAttributes;
         }
 
-		private SafeBag(Asn1Sequence seq)
+        public SafeBag(DerObjectIdentifier oid, Asn1Object obj, Asn1Set bagAttributes)
         {
-            this.bagID = (DerObjectIdentifier)seq[0];
-            this.bagValue = ((Asn1TaggedObject)seq[1]).GetExplicitBaseObject().ToAsn1Object();
-            if (seq.Count == 3)
-            {
-                this.bagAttributes = (Asn1Set)seq[2];
-            }
+            m_bagID = oid ?? throw new ArgumentNullException(nameof(oid));
+            m_bagValue = obj ?? throw new ArgumentNullException(nameof(obj));
+            m_bagAttributes = bagAttributes;
         }
 
-		public DerObjectIdentifier BagID
-		{
-			get { return bagID; }
-		}
+        public DerObjectIdentifier BagID => m_bagID;
 
-		public Asn1Object BagValue
-		{
-			get { return bagValue; }
-		}
+        public Asn1Object BagValue => m_bagValue;
 
-		public Asn1Set BagAttributes
-		{
-			get { return bagAttributes; }
-		}
+        public Asn1Set BagAttributes => m_bagAttributes;
 
         public override Asn1Object ToAsn1Object()
         {
-            Asn1EncodableVector v = new Asn1EncodableVector(bagID, new DerTaggedObject(0, bagValue));
-            v.AddOptional(bagAttributes);
+            Asn1EncodableVector v = new Asn1EncodableVector(3);
+            v.Add(m_bagID, new DerTaggedObject(0, m_bagValue));
+            v.AddOptional(m_bagAttributes);
             return new DerSequence(v);
         }
     }
diff --git a/crypto/src/asn1/pkcs/SignedData.cs b/crypto/src/asn1/pkcs/SignedData.cs
index e309d9245..de9c758fb 100644
--- a/crypto/src/asn1/pkcs/SignedData.cs
+++ b/crypto/src/asn1/pkcs/SignedData.cs
@@ -8,111 +8,72 @@ namespace Org.BouncyCastle.Asn1.Pkcs
     public class SignedData
         : Asn1Encodable
     {
-        private readonly DerInteger		version;
-        private readonly Asn1Set		digestAlgorithms;
-        private readonly ContentInfo	contentInfo;
-        private readonly Asn1Set		certificates;
-        private readonly Asn1Set		crls;
-        private readonly Asn1Set		signerInfos;
-
         public static SignedData GetInstance(object obj)
         {
             if (obj == null)
                 return null;
-            SignedData existing = obj as SignedData;
-            if (existing != null)
-                return existing;
+            if (obj is SignedData signedData)
+                return signedData;
             return new SignedData(Asn1Sequence.GetInstance(obj));
         }
 
-        public SignedData(
-            DerInteger        _version,
-            Asn1Set           _digestAlgorithms,
-            ContentInfo       _contentInfo,
-            Asn1Set           _certificates,
-            Asn1Set           _crls,
-            Asn1Set           _signerInfos)
+        public static SignedData GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
         {
-            version          = _version;
-            digestAlgorithms = _digestAlgorithms;
-            contentInfo      = _contentInfo;
-            certificates     = _certificates;
-            crls             = _crls;
-            signerInfos      = _signerInfos;
+            return new SignedData(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
         }
 
-        private SignedData(
-            Asn1Sequence seq)
-        {
-            var e = seq.GetEnumerator();
-
-            e.MoveNext();
-            version = (DerInteger) e.Current;
-
-            e.MoveNext();
-            digestAlgorithms = (Asn1Set) e.Current;
+        private readonly DerInteger m_version;
+        private readonly Asn1Set m_digestAlgorithms;
+        private readonly ContentInfo m_contentInfo;
+        private readonly Asn1Set m_certificates;
+        private readonly Asn1Set m_crls;
+        private readonly Asn1Set m_signerInfos;
 
-            e.MoveNext();
-            contentInfo = ContentInfo.GetInstance(e.Current);
-
-            while (e.MoveNext())
-            {
-                Asn1Object o = e.Current.ToAsn1Object();
-
-                //
-                // an interesting feature of SignedData is that there appear to be varying implementations...
-                // for the moment we ignore anything which doesn't fit.
-                //
-                if (o is Asn1TaggedObject tagged)
-                {
-                    switch (tagged.TagNo)
-                    {
-                    case 0:
-                        certificates = Asn1Set.GetInstance(tagged, false);
-                        break;
-                    case 1:
-                        crls = Asn1Set.GetInstance(tagged, false);
-                        break;
-                    default:
-                        throw new ArgumentException("unknown tag value " + tagged.TagNo);
-                    }
-                }
-                else
-                {
-                    signerInfos = (Asn1Set) o;
-                }
-            }
-        }
-
-        public DerInteger Version
+        private SignedData(Asn1Sequence seq)
         {
-            get { return version; }
+            int count = seq.Count, pos = 0;
+            if (count < 4 || count > 6)
+                throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
+
+            m_version = DerInteger.GetInstance(seq[pos++]);
+            m_digestAlgorithms = Asn1Set.GetInstance(seq[pos++]);
+            m_contentInfo = ContentInfo.GetInstance(seq[pos++]);
+            m_certificates = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 0, false, Asn1Set.GetInstance);
+            m_crls = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 1, false, Asn1Set.GetInstance);
+            m_signerInfos = Asn1Set.GetInstance(seq[pos++]);
+
+            if (pos != count)
+                throw new ArgumentException("Unexpected elements in sequence", nameof(seq));
         }
 
-        public Asn1Set DigestAlgorithms
+        // TODO[api] Improve parameter names
+        public SignedData(
+            DerInteger _version,
+            Asn1Set _digestAlgorithms,
+            ContentInfo _contentInfo,
+            Asn1Set _certificates,
+            Asn1Set _crls,
+            Asn1Set _signerInfos)
         {
-            get { return digestAlgorithms; }
+            m_version = _version ?? throw new ArgumentNullException(nameof(_version));
+            m_digestAlgorithms = _digestAlgorithms ?? throw new ArgumentNullException(nameof(_digestAlgorithms));
+            m_contentInfo = _contentInfo ?? throw new ArgumentNullException(nameof(_contentInfo));
+            m_certificates = _certificates;
+            m_crls = _crls;
+            m_signerInfos = _signerInfos ?? throw new ArgumentNullException(nameof(_signerInfos));
         }
 
-        public ContentInfo ContentInfo
-        {
-            get { return contentInfo; }
-        }
+        public DerInteger Version => m_version;
 
-        public Asn1Set Certificates
-        {
-            get { return certificates; }
-        }
+        public Asn1Set DigestAlgorithms => m_digestAlgorithms;
 
-        public Asn1Set Crls
-        {
-            get { return crls; }
-        }
+        public ContentInfo ContentInfo => m_contentInfo;
 
-        public Asn1Set SignerInfos
-        {
-            get { return signerInfos; }
-        }
+        public Asn1Set Certificates => m_certificates;
+
+        public Asn1Set Crls => m_crls;
+
+        public Asn1Set SignerInfos => m_signerInfos;
 
         /**
          * Produce an object suitable for an Asn1OutputStream.
@@ -131,10 +92,11 @@ namespace Org.BouncyCastle.Asn1.Pkcs
          */
         public override Asn1Object ToAsn1Object()
         {
-            Asn1EncodableVector v = new Asn1EncodableVector(version, digestAlgorithms, contentInfo);
-            v.AddOptionalTagged(false, 0, certificates);
-            v.AddOptionalTagged(false, 1, crls);
-            v.Add(signerInfos);
+            Asn1EncodableVector v = new Asn1EncodableVector(6);
+            v.Add(m_version, m_digestAlgorithms, m_contentInfo);
+            v.AddOptionalTagged(false, 0, m_certificates);
+            v.AddOptionalTagged(false, 1, m_crls);
+            v.Add(m_signerInfos);
             return new BerSequence(v);
         }
     }
diff --git a/crypto/src/asn1/pkcs/SignerInfo.cs b/crypto/src/asn1/pkcs/SignerInfo.cs
index 532a564f3..01d9de98e 100644
--- a/crypto/src/asn1/pkcs/SignerInfo.cs
+++ b/crypto/src/asn1/pkcs/SignerInfo.cs
@@ -1,3 +1,5 @@
+using System;
+
 using Org.BouncyCastle.Asn1.X509;
 
 namespace Org.BouncyCastle.Asn1.Pkcs
@@ -8,97 +10,82 @@ namespace Org.BouncyCastle.Asn1.Pkcs
     public class SignerInfo
         : Asn1Encodable
     {
-        private DerInteger              version;
-        private IssuerAndSerialNumber   issuerAndSerialNumber;
-        private AlgorithmIdentifier     digAlgorithm;
-        private Asn1Set                 authenticatedAttributes;
-        private AlgorithmIdentifier     digEncryptionAlgorithm;
-        private Asn1OctetString         encryptedDigest;
-        private Asn1Set                 unauthenticatedAttributes;
-
         public static SignerInfo GetInstance(object obj)
         {
             if (obj == null)
                 return null;
             if (obj is SignerInfo signerInfo)
                 return signerInfo;
+#pragma warning disable CS0618 // Type or member is obsolete
             return new SignerInfo(Asn1Sequence.GetInstance(obj));
+#pragma warning restore CS0618 // Type or member is obsolete
+        }
+
+        public static SignerInfo GetInstance(Asn1TaggedObject taggedObject, bool declaredExplicit)
+        {
+#pragma warning disable CS0618 // Type or member is obsolete
+            return new SignerInfo(Asn1Sequence.GetInstance(taggedObject, declaredExplicit));
+#pragma warning restore CS0618 // Type or member is obsolete
         }
 
-		public SignerInfo(
-            DerInteger              version,
-            IssuerAndSerialNumber   issuerAndSerialNumber,
-            AlgorithmIdentifier     digAlgorithm,
-            Asn1Set                 authenticatedAttributes,
-            AlgorithmIdentifier     digEncryptionAlgorithm,
-            Asn1OctetString         encryptedDigest,
-            Asn1Set                 unauthenticatedAttributes)
+        private readonly DerInteger m_version;
+        private readonly IssuerAndSerialNumber m_issuerAndSerialNumber;
+        private readonly AlgorithmIdentifier m_digAlgorithm;
+        private readonly Asn1Set m_authenticatedAttributes;
+        private readonly AlgorithmIdentifier m_digEncryptionAlgorithm;
+        private readonly Asn1OctetString m_encryptedDigest;
+        private readonly Asn1Set m_unauthenticatedAttributes;
+
+        [Obsolete("Use 'GetInstance' instead")]
+        public SignerInfo(Asn1Sequence seq)
         {
-            this.version = version;
-            this.issuerAndSerialNumber = issuerAndSerialNumber;
-            this.digAlgorithm = digAlgorithm;
-            this.authenticatedAttributes = authenticatedAttributes;
-            this.digEncryptionAlgorithm = digEncryptionAlgorithm;
-            this.encryptedDigest = encryptedDigest;
-            this.unauthenticatedAttributes = unauthenticatedAttributes;
+            int count = seq.Count, pos = 0;
+            if (count < 5 || count > 7)
+                throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
+
+            m_version = DerInteger.GetInstance(seq[pos++]);
+            m_issuerAndSerialNumber = IssuerAndSerialNumber.GetInstance(seq[pos++]);
+            m_digAlgorithm = AlgorithmIdentifier.GetInstance(seq[pos++]);
+            m_authenticatedAttributes = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 0, false, Asn1Set.GetInstance);
+            m_digEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(seq[pos++]);
+            m_encryptedDigest = Asn1OctetString.GetInstance(seq[pos++]);
+            m_unauthenticatedAttributes = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 1, false, Asn1Set.GetInstance);
+
+            if (pos != count)
+                throw new ArgumentException("Unexpected elements in sequence", nameof(seq));
         }
 
-		public SignerInfo(
-            Asn1Sequence seq)
+        public SignerInfo(
+            DerInteger version,
+            IssuerAndSerialNumber issuerAndSerialNumber,
+            AlgorithmIdentifier digAlgorithm,
+            Asn1Set authenticatedAttributes,
+            AlgorithmIdentifier digEncryptionAlgorithm,
+            Asn1OctetString encryptedDigest,
+            Asn1Set unauthenticatedAttributes)
         {
-            var e = seq.GetEnumerator();
-
-			e.MoveNext();
-            version = (DerInteger) e.Current;
-
-			e.MoveNext();
-            issuerAndSerialNumber = IssuerAndSerialNumber.GetInstance(e.Current);
-
-			e.MoveNext();
-            digAlgorithm = AlgorithmIdentifier.GetInstance(e.Current);
-
-			e.MoveNext();
-            var obj = e.Current;
-
-			if (obj is Asn1TaggedObject tagged)
-            {
-                authenticatedAttributes = Asn1Set.GetInstance(tagged, false);
-
-				e.MoveNext();
-                digEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(e.Current);
-            }
-            else
-            {
-                authenticatedAttributes = null;
-                digEncryptionAlgorithm = AlgorithmIdentifier.GetInstance(obj);
-            }
-
-			e.MoveNext();
-            encryptedDigest = Asn1OctetString.GetInstance(e.Current);
-
-			if (e.MoveNext())
-            {
-                unauthenticatedAttributes = Asn1Set.GetInstance((Asn1TaggedObject)e.Current, false);
-            }
-            else
-            {
-                unauthenticatedAttributes = null;
-            }
+            m_version = version ?? throw new ArgumentNullException(nameof(version));
+            m_issuerAndSerialNumber = issuerAndSerialNumber ?? throw new ArgumentNullException(nameof(issuerAndSerialNumber));
+            m_digAlgorithm = digAlgorithm ?? throw new ArgumentNullException(nameof(digAlgorithm));
+            m_authenticatedAttributes = authenticatedAttributes;
+            m_digEncryptionAlgorithm = digEncryptionAlgorithm ?? throw new ArgumentNullException(nameof(digEncryptionAlgorithm));
+            m_encryptedDigest = encryptedDigest ?? throw new ArgumentNullException(nameof(encryptedDigest));
+            m_unauthenticatedAttributes = unauthenticatedAttributes;
         }
 
-		public DerInteger Version { get { return version; } }
+        public DerInteger Version => m_version;
 
-		public IssuerAndSerialNumber IssuerAndSerialNumber { get { return issuerAndSerialNumber; } }
+		public IssuerAndSerialNumber IssuerAndSerialNumber => m_issuerAndSerialNumber;
 
-		public Asn1Set AuthenticatedAttributes { get { return authenticatedAttributes; } }
+        public Asn1Set AuthenticatedAttributes => m_authenticatedAttributes;
 
-		public AlgorithmIdentifier DigestAlgorithm { get { return digAlgorithm; } }
+        public AlgorithmIdentifier DigestAlgorithm => m_digAlgorithm;
 
-		public Asn1OctetString EncryptedDigest { get { return encryptedDigest; } }
+		public Asn1OctetString EncryptedDigest => m_encryptedDigest;
 
-		public AlgorithmIdentifier DigestEncryptionAlgorithm { get { return digEncryptionAlgorithm; } }
+		public AlgorithmIdentifier DigestEncryptionAlgorithm => m_digEncryptionAlgorithm;
 
-		public Asn1Set UnauthenticatedAttributes { get { return unauthenticatedAttributes; } }
+		public Asn1Set UnauthenticatedAttributes => m_unauthenticatedAttributes;
 
 		/**
          * Produce an object suitable for an Asn1OutputStream.
@@ -122,10 +109,11 @@ namespace Org.BouncyCastle.Asn1.Pkcs
          */
         public override Asn1Object ToAsn1Object()
         {
-            Asn1EncodableVector v = new Asn1EncodableVector(version, issuerAndSerialNumber, digAlgorithm);
-            v.AddOptionalTagged(false, 0, authenticatedAttributes);
-            v.Add(digEncryptionAlgorithm, encryptedDigest);
-            v.AddOptionalTagged(false, 1, unauthenticatedAttributes);
+            Asn1EncodableVector v = new Asn1EncodableVector(7);
+            v.Add(m_version, m_issuerAndSerialNumber, m_digAlgorithm);
+            v.AddOptionalTagged(false, 0, m_authenticatedAttributes);
+            v.Add(m_digEncryptionAlgorithm, m_encryptedDigest);
+            v.AddOptionalTagged(false, 1, m_unauthenticatedAttributes);
             return new DerSequence(v);
         }
     }
diff --git a/crypto/src/security/PbeUtilities.cs b/crypto/src/security/PbeUtilities.cs
index 74fda8ce8..6fefbe270 100644
--- a/crypto/src/security/PbeUtilities.cs
+++ b/crypto/src/security/PbeUtilities.cs
@@ -453,7 +453,7 @@ namespace Org.BouncyCastle.Security
                 DerObjectIdentifier encOid = encScheme.Algorithm;
                 Asn1Object encParams = encScheme.Parameters.ToAsn1Object();
 
-                Pbkdf2Params pbeParams = Pbkdf2Params.GetInstance(s2p.KeyDerivationFunc.Parameters.ToAsn1Object());
+                Pbkdf2Params pbeParams = Pbkdf2Params.GetInstance(s2p.KeyDerivationFunc.Parameters);
                 IDigest digest = DigestUtilities.GetDigest(pbeParams.Prf.Algorithm);
 
                 byte[] iv;
diff --git a/crypto/src/security/PrivateKeyFactory.cs b/crypto/src/security/PrivateKeyFactory.cs
index 205a604a8..cf47eb272 100644
--- a/crypto/src/security/PrivateKeyFactory.cs
+++ b/crypto/src/security/PrivateKeyFactory.cs
@@ -67,8 +67,7 @@ namespace Org.BouncyCastle.Security
             //			else if (algOid.Equals(X9ObjectIdentifiers.DHPublicNumber))
             else if (algOid.Equals(PkcsObjectIdentifiers.DhKeyAgreement))
             {
-                DHParameter para = new DHParameter(
-                    Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
+                DHParameter para = DHParameter.GetInstance(algID.Parameters);
                 DerInteger derX = (DerInteger)keyInfo.ParsePrivateKey();
 
                 BigInteger lVal = para.L;
diff --git a/crypto/src/security/PublicKeyFactory.cs b/crypto/src/security/PublicKeyFactory.cs
index dd34b84ff..234847870 100644
--- a/crypto/src/security/PublicKeyFactory.cs
+++ b/crypto/src/security/PublicKeyFactory.cs
@@ -317,7 +317,7 @@ namespace Org.BouncyCastle.Security
         private static DHPublicKeyParameters ReadPkcsDHParam(DerObjectIdentifier algOid,
             BigInteger y, Asn1Sequence seq)
         {
-            DHParameter para = new DHParameter(seq);
+            DHParameter para = DHParameter.GetInstance(seq);
 
             BigInteger lVal = para.L;
             int l = lVal == null ? 0 : lVal.IntValue;
diff --git a/crypto/test/src/crypto/test/Pkcs5Test.cs b/crypto/test/src/crypto/test/Pkcs5Test.cs
index d3d22172f..649fe69e5 100644
--- a/crypto/test/src/crypto/test/Pkcs5Test.cs
+++ b/crypto/test/src/crypto/test/Pkcs5Test.cs
@@ -94,7 +94,7 @@ namespace Org.BouncyCastle.Crypto.Tests
                 EncryptedPrivateKeyInfo info = null;
                 try
                 {
-                    info = EncryptedPrivateKeyInfo.GetInstance(Asn1Object.FromByteArray(sample));
+                    info = EncryptedPrivateKeyInfo.GetInstance(sample);
                 }
                 catch (System.Exception e)
                 {
-- 
cgit 1.4.1