summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crypto/src/cmp/GeneralPkiMessage.cs5
-rw-r--r--crypto/src/crmf/PKMacBuilder.cs4
-rw-r--r--crypto/src/ocsp/CertificateID.cs58
-rw-r--r--crypto/src/tsp/TimeStampToken.cs20
-rw-r--r--crypto/src/x509/AttributeCertificateHolder.cs276
-rw-r--r--crypto/src/x509/PrincipalUtil.cs18
-rw-r--r--crypto/src/x509/X509Utilities.cs38
-rw-r--r--crypto/src/x509/X509V2AttributeCertificateGenerator.cs2
-rw-r--r--crypto/src/x509/X509V3CertificateGenerator.cs28
-rw-r--r--crypto/src/x509/extension/AuthorityKeyIdentifierStructure.cs6
-rw-r--r--crypto/test/src/cms/test/EnvelopedDataStreamTest.cs2
-rw-r--r--crypto/test/src/cms/test/EnvelopedDataTest.cs2
-rw-r--r--crypto/test/src/ocsp/test/OCSPTest.cs22
-rw-r--r--crypto/test/src/test/AttrCertSelectorTest.cs2
-rw-r--r--crypto/test/src/test/TestUtilities.cs6
-rw-r--r--crypto/test/src/test/X509StoreTest.cs6
16 files changed, 216 insertions, 279 deletions
diff --git a/crypto/src/cmp/GeneralPkiMessage.cs b/crypto/src/cmp/GeneralPkiMessage.cs
index 09c02434c..3ef4f4630 100644
--- a/crypto/src/cmp/GeneralPkiMessage.cs
+++ b/crypto/src/cmp/GeneralPkiMessage.cs
@@ -7,10 +7,7 @@ namespace Org.BouncyCastle.Cmp
     {
         private readonly PkiMessage m_pkiMessage;
 
-        private static PkiMessage ParseBytes(byte[] encoding)
-        {
-            return PkiMessage.GetInstance(Asn1Object.FromByteArray(encoding));
-        }
+        private static PkiMessage ParseBytes(byte[] encoding) => PkiMessage.GetInstance(encoding);
 
         /// <summary>
         /// Wrap a PKIMessage ASN.1 structure.
diff --git a/crypto/src/crmf/PKMacBuilder.cs b/crypto/src/crmf/PKMacBuilder.cs
index ac9e7ca18..e8494c7a6 100644
--- a/crypto/src/crmf/PKMacBuilder.cs
+++ b/crypto/src/crmf/PKMacBuilder.cs
@@ -21,7 +21,7 @@ namespace Org.BouncyCastle.Crmf
         private readonly KeyParameter m_key;
         private readonly PbmParameter m_parameters;
 
-        public PKMacFactory(byte[] key, PbmParameter parameters)
+        internal PKMacFactory(byte[] key, PbmParameter parameters)
         {
             m_key = new KeyParameter(key);
             m_parameters = parameters;
@@ -47,7 +47,7 @@ namespace Org.BouncyCastle.Crmf
         private PbmParameter parameters;
         private int iterationCount;
         private int saltLength = 20;
-        private int maxIterations;
+        private readonly int maxIterations;
 
         /// <summary>
         /// Default, IterationCount = 1000, OIW=IdSha1, Mac=HmacSHA1
diff --git a/crypto/src/ocsp/CertificateID.cs b/crypto/src/ocsp/CertificateID.cs
index 3b4c78248..fd482f8d8 100644
--- a/crypto/src/ocsp/CertificateID.cs
+++ b/crypto/src/ocsp/CertificateID.cs
@@ -2,7 +2,9 @@ using System;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.Ocsp;
+using Org.BouncyCastle.Asn1.Oiw;
 using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Math;
 using Org.BouncyCastle.Security;
 using Org.BouncyCastle.X509;
@@ -12,10 +14,13 @@ namespace Org.BouncyCastle.Ocsp
     public class CertificateID
 		: IEquatable<CertificateID>
 	{
-        // OiwObjectIdentifiers.IdSha1.Id
+		[Obsolete("Use 'OiwObjectIdentifiers.IdSha1.Id' instead")]
 		public const string HashSha1 = "1.3.14.3.2.26";
 
-		private readonly CertID m_id;
+		public static readonly AlgorithmIdentifier DigestSha1 = new AlgorithmIdentifier(
+            OiwObjectIdentifiers.IdSha1, DerNull.Instance);
+
+        private readonly CertID m_id;
 
 		public CertificateID(CertID id)
 		{
@@ -27,15 +32,26 @@ namespace Org.BouncyCastle.Ocsp
 		 * certificate it signed.
 		 * @exception OcspException if any problems occur creating the id fields.
 		 */
+		[Obsolete("Will be removed")]
 		public CertificateID(string hashAlgorithm, X509Certificate issuerCert, BigInteger serialNumber)
 		{
-			AlgorithmIdentifier hashAlg = new AlgorithmIdentifier(
+			AlgorithmIdentifier digestAlgorithm = new AlgorithmIdentifier(
 				new DerObjectIdentifier(hashAlgorithm), DerNull.Instance);
 
-			m_id = CreateCertID(hashAlg, issuerCert, new DerInteger(serialNumber));
+			m_id = CreateCertID(digestAlgorithm, issuerCert, new DerInteger(serialNumber));
 		}
 
-		public string HashAlgOid => m_id.HashAlgorithm.Algorithm.Id;
+        public CertificateID(AlgorithmIdentifier digestAlgorithm, X509Certificate issuerCert, BigInteger serialNumber)
+        {
+            m_id = CreateCertID(digestAlgorithm, issuerCert, new DerInteger(serialNumber));
+        }
+
+        public CertificateID(IDigestFactory digestFactory, X509Certificate issuerCert, BigInteger serialNumber)
+        {
+            m_id = CreateCertID(digestFactory, issuerCert, new DerInteger(serialNumber));
+        }
+
+        public string HashAlgOid => m_id.HashAlgorithm.Algorithm.Id;
 
 		public byte[] GetIssuerNameHash() => m_id.IssuerNameHash.GetOctets();
 
@@ -52,6 +68,14 @@ namespace Org.BouncyCastle.Ocsp
 			return CreateCertID(m_id.HashAlgorithm, issuerCert, m_id.SerialNumber).Equals(m_id);
 		}
 
+        public bool MatchesIssuer(IDigestFactory digestFactory, X509Certificate issuerCert)
+        {
+            if (!m_id.HashAlgorithm.Equals(digestFactory.AlgorithmDetails))
+                throw new ArgumentException("digest factory does not match required digest algorithm");
+
+            return CreateCertID(digestFactory, issuerCert, m_id.SerialNumber).Equals(m_id);
+        }
+
         public CertID ToAsn1Object() => m_id;
 
         public bool Equals(CertificateID other) => this == other || m_id.Equals(other?.m_id);
@@ -82,7 +106,7 @@ namespace Org.BouncyCastle.Ocsp
 		{
 			try
 			{
-				X509Name issuerName = PrincipalUtilities.GetSubjectX509Principal(issuerCert);
+				X509Name issuerName = issuerCert.SubjectDN;
 				byte[] issuerNameHash = X509Utilities.CalculateDigest(digestAlgorithm, issuerName);
 
 				byte[] issuerKey = issuerCert.SubjectPublicKeyInfo.PublicKey.GetBytes();
@@ -96,5 +120,25 @@ namespace Org.BouncyCastle.Ocsp
 				throw new OcspException("problem creating ID: " + e, e);
 			}
 		}
-	}
+
+        private static CertID CreateCertID(IDigestFactory digestFactory, X509Certificate issuerCert,
+            DerInteger serialNumber)
+        {
+            try
+            {
+                X509Name issuerName = issuerCert.SubjectDN;
+                byte[] issuerNameHash = X509Utilities.CalculateDigest(digestFactory, issuerName);
+
+                byte[] issuerKey = issuerCert.SubjectPublicKeyInfo.PublicKey.GetBytes();
+                byte[] issuerKeyHash = X509Utilities.CalculateDigest(digestFactory, issuerKey, 0, issuerKey.Length);
+
+                return new CertID((AlgorithmIdentifier)digestFactory.AlgorithmDetails,
+					new DerOctetString(issuerNameHash), new DerOctetString(issuerKeyHash), serialNumber);
+            }
+            catch (Exception e)
+            {
+                throw new OcspException("problem creating ID: " + e, e);
+            }
+        }
+    }
 }
diff --git a/crypto/src/tsp/TimeStampToken.cs b/crypto/src/tsp/TimeStampToken.cs
index 8e9f09723..342787982 100644
--- a/crypto/src/tsp/TimeStampToken.cs
+++ b/crypto/src/tsp/TimeStampToken.cs
@@ -8,6 +8,7 @@ using Org.BouncyCastle.Asn1.Oiw;
 using Org.BouncyCastle.Asn1.Pkcs;
 using Org.BouncyCastle.Asn1.Tsp;
 using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Cmp;
 using Org.BouncyCastle.Cms;
 using Org.BouncyCastle.Security;
 using Org.BouncyCastle.Security.Certificates;
@@ -153,30 +154,29 @@ namespace Org.BouncyCastle.Tsp
 		 * A successful call to validate means all the above are true.
 		 * </p>
 		 */
-		public void Validate(
-			X509Certificate cert)
+		public void Validate(X509Certificate cert)
 		{
 			try
 			{
-				byte[] hash = DigestUtilities.CalculateDigest(
-					certID.GetHashAlgorithmName(), cert.GetEncoded());
+				byte[] hash = DigestUtilities.CalculateDigest(certID.GetHashAlgorithmName(), cert.GetEncoded());
 
 				if (!Arrays.FixedTimeEquals(certID.GetCertHash(), hash))
 					throw new TspValidationException("certificate hash does not match certID hash.");
 
-				if (certID.IssuerSerial != null)
+				var issuerSerial = certID.IssuerSerial;
+				if (issuerSerial != null)
 				{
-					if (!certID.IssuerSerial.Serial.HasValue(cert.SerialNumber))
+					if (!issuerSerial.Serial.HasValue(cert.SerialNumber))
 						throw new TspValidationException("certificate serial number does not match certID for signature.");
 
 					GeneralName[] names = certID.IssuerSerial.Issuer.GetNames();
-					X509Name principal = PrincipalUtilities.GetIssuerX509Principal(cert);
+					X509Name principal = cert.IssuerDN;
 					bool found = false;
 
 					for (int i = 0; i != names.Length; i++)
 					{
-						if (names[i].TagNo == 4
-							&& X509Name.GetInstance(names[i].Name).Equivalent(principal))
+						if (names[i].TagNo == GeneralName.DirectoryName &&
+							X509Name.GetInstance(names[i].Name).Equivalent(principal))
 						{
 							found = true;
 							break;
@@ -184,9 +184,7 @@ namespace Org.BouncyCastle.Tsp
 					}
 
 					if (!found)
-					{
 						throw new TspValidationException("certificate name does not match certID for signature. ");
-					}
 				}
 
 				TspUtil.ValidateCertificate(cert);
diff --git a/crypto/src/x509/AttributeCertificateHolder.cs b/crypto/src/x509/AttributeCertificateHolder.cs
index 9122a809f..1df5b1a56 100644
--- a/crypto/src/x509/AttributeCertificateHolder.cs
+++ b/crypto/src/x509/AttributeCertificateHolder.cs
@@ -1,73 +1,60 @@
 using System;
+using System.Collections.Generic;
 
 using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Crypto;
 using Org.BouncyCastle.Math;
 using Org.BouncyCastle.Security;
-using Org.BouncyCastle.Security.Certificates;
 using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.Collections;
 
 namespace Org.BouncyCastle.X509
 {
-	/// <remarks>
-	/// The Holder object.
-	/// <pre>
- 	/// Holder ::= SEQUENCE {
- 	///		baseCertificateID   [0] IssuerSerial OPTIONAL,
- 	///			-- the issuer and serial number of
- 	///			-- the holder's Public Key Certificate
- 	///		entityName          [1] GeneralNames OPTIONAL,
- 	///			-- the name of the claimant or role
- 	///		objectDigestInfo    [2] ObjectDigestInfo OPTIONAL
- 	///			-- used to directly authenticate the holder,
- 	///			-- for example, an executable
- 	/// }
-	/// </pre>
-	/// </remarks>
-	public class AttributeCertificateHolder
-		//: CertSelector, Selector
-		: ISelector<X509Certificate>
+    /// <remarks>
+    /// The Holder object.
+    /// <pre>
+    /// Holder ::= SEQUENCE {
+    ///		baseCertificateID   [0] IssuerSerial OPTIONAL,
+    ///			-- the issuer and serial number of
+    ///			-- the holder's Public Key Certificate
+    ///		entityName          [1] GeneralNames OPTIONAL,
+    ///			-- the name of the claimant or role
+    ///		objectDigestInfo    [2] ObjectDigestInfo OPTIONAL
+    ///			-- used to directly authenticate the holder,
+    ///			-- for example, an executable
+    /// }
+    /// </pre>
+    /// </remarks>
+    public class AttributeCertificateHolder
+		: IEquatable<AttributeCertificateHolder>, ISelector<X509Certificate>
 	{
-		internal readonly Holder holder;
+		internal readonly Holder m_holder;
 
-		internal AttributeCertificateHolder(
-			Asn1Sequence seq)
+		internal AttributeCertificateHolder(Asn1Sequence seq)
 		{
-			holder = Holder.GetInstance(seq);
+			m_holder = Holder.GetInstance(seq);
 		}
 
-		public AttributeCertificateHolder(
-			X509Name	issuerName,
-			BigInteger	serialNumber)
+		public AttributeCertificateHolder(X509Name issuerName, BigInteger serialNumber)
 		{
-			holder = new Holder(
+			m_holder = new Holder(
 				new IssuerSerial(
 					GenerateGeneralNames(issuerName),
 					new DerInteger(serialNumber)));
 		}
 
-		public AttributeCertificateHolder(
-			X509Certificate	cert)
+		public AttributeCertificateHolder(X509Certificate cert)
 		{
-			X509Name name;
-			try
-			{
-				name = PrincipalUtilities.GetIssuerX509Principal(cert);
-			}
-			catch (Exception e)
-			{
-				throw new CertificateParsingException(e.Message);
-			}
-
-			holder = new Holder(new IssuerSerial(GenerateGeneralNames(name), new DerInteger(cert.SerialNumber)));
+			m_holder = new Holder(
+				new IssuerSerial(
+					GenerateGeneralNames(cert.IssuerDN),
+					new DerInteger(cert.SerialNumber)));
 		}
 
-		public AttributeCertificateHolder(
-			X509Name principal)
+		public AttributeCertificateHolder(X509Name principal)
 		{
-			holder = new Holder(GenerateGeneralNames(principal));
+			m_holder = new Holder(GenerateGeneralNames(principal));
 		}
 
 		/**
@@ -93,16 +80,14 @@ namespace Org.BouncyCastle.X509
 		 *            <code>otherObjectDigest</code>.
 		 * @param objectDigest The hash value.
 		 */
-		public AttributeCertificateHolder(
-			int		digestedObjectType,
-			string	digestAlgorithm,
-			string	otherObjectTypeID,
-			byte[]	objectDigest)
+		public AttributeCertificateHolder(int digestedObjectType, string digestAlgorithm, string otherObjectTypeID,
+			byte[] objectDigest)
 		{
-			// TODO Allow 'objectDigest' to be null?
+			var digestAlgorithmID = new AlgorithmIdentifier(new DerObjectIdentifier(digestAlgorithm));
+			var objectDigestInfo = new ObjectDigestInfo(digestedObjectType, otherObjectTypeID, digestAlgorithmID,
+				Arrays.Clone(objectDigest));
 
-			holder = new Holder(new ObjectDigestInfo(digestedObjectType, otherObjectTypeID,
-				new AlgorithmIdentifier(new DerObjectIdentifier(digestAlgorithm)), Arrays.Clone(objectDigest)));
+            m_holder = new Holder(objectDigestInfo);
 		}
 
 		/**
@@ -124,7 +109,7 @@ namespace Org.BouncyCastle.X509
 		{
 			get
 			{
-				ObjectDigestInfo odi = holder.ObjectDigestInfo;
+				ObjectDigestInfo odi = m_holder.ObjectDigestInfo;
 
 				return odi == null
 					?   -1
@@ -138,31 +123,14 @@ namespace Org.BouncyCastle.X509
 		 * @return The other object type ID or <code>null</code> if no object
 		 *         digest info is set.
 		 */
-		public string DigestAlgorithm
-		{
-			get
-			{
-				ObjectDigestInfo odi = holder.ObjectDigestInfo;
-
-				return odi == null
-					?	null
-					:	odi.DigestAlgorithm.Algorithm.Id;
-			}
-		}
+		public string DigestAlgorithm => m_holder.ObjectDigestInfo?.DigestAlgorithm.Algorithm.Id;
 
 		/**
 		 * Returns the hash if an object digest info is used.
 		 *
 		 * @return The hash or <code>null</code> if no object digest info is set.
 		 */
-		public byte[] GetObjectDigest()
-		{
-			ObjectDigestInfo odi = holder.ObjectDigestInfo;
-
-			return odi == null
-				?	null
-				:	odi.ObjectDigest.GetBytes();
-		}
+		public byte[] GetObjectDigest() => m_holder.ObjectDigestInfo?.ObjectDigest.GetBytes();
 
 		/**
 		 * Returns the digest algorithm ID if an object digest info is used.
@@ -170,43 +138,20 @@ namespace Org.BouncyCastle.X509
 		 * @return The digest algorithm ID or <code>null</code> if no object
 		 *         digest info is set.
 		 */
-		public string OtherObjectTypeID
-		{
-			get
-			{
-				ObjectDigestInfo odi = holder.ObjectDigestInfo;
+		public string OtherObjectTypeID => m_holder.ObjectDigestInfo?.OtherObjectTypeID.Id;
 
-				return odi == null
-					?	null
-					:	odi.OtherObjectTypeID.Id;
-			}
-		}
-
-		private GeneralNames GenerateGeneralNames(
-			X509Name principal)
-		{
-//			return GeneralNames.GetInstance(new DerSequence(new GeneralName(principal)));
-			return new GeneralNames(new GeneralName(principal));
-		}
+		private GeneralNames GenerateGeneralNames(X509Name principal) => new GeneralNames(new GeneralName(principal));
 
-		private bool MatchesDN(
-			X509Name		subject,
-			GeneralNames	targets)
+		private bool MatchesDN(X509Name subject, GeneralNames targets)
 		{
-			GeneralName[] names = targets.GetNames();
-
-			for (int i = 0; i != names.Length; i++)
+			foreach (var gn in targets.GetNames())
 			{
-				GeneralName gn = names[i];
-
 				if (gn.TagNo == GeneralName.DirectoryName)
 				{
 					try
 					{
 						if (X509Name.GetInstance(gn.Name).Equivalent(subject))
-						{
 							return true;
-						}
 					}
 					catch (Exception)
 					{
@@ -217,59 +162,18 @@ namespace Org.BouncyCastle.X509
 			return false;
 		}
 
-		private object[] GetNames(
-			GeneralName[] names)
+		private X509Name[] GetPrincipals(GeneralNames generalNames)
 		{
-            int count = 0;
-            for (int i = 0; i != names.Length; i++)
+			var names = generalNames.GetNames();
+			var result = new List<X509Name>(names.Length);
+			foreach (var name in names)
             {
-                if (names[i].TagNo == GeneralName.DirectoryName)
+                if (GeneralName.DirectoryName == name.TagNo)
                 {
-                    ++count;
+					result.Add(X509Name.GetInstance(name.Name));
                 }
-            }
-
-            object[] result = new object[count];
-
-            int pos = 0;
-            for (int i = 0; i != names.Length; i++)
-            {
-                if (names[i].TagNo == GeneralName.DirectoryName)
-                {
-                    result[pos++] = X509Name.GetInstance(names[i].Name);
-                }
-            }
-
-            return result;
-        }
-
-		private X509Name[] GetPrincipals(
-			GeneralNames names)
-		{
-			object[] p = this.GetNames(names.GetNames());
-
-            int count = 0;
-
-            for (int i = 0; i != p.Length; i++)
-			{
-				if (p[i] is X509Name)
-				{
-                    ++count;
-				}
 			}
-
-            X509Name[] result = new X509Name[count];
-
-            int pos = 0;
-            for (int i = 0; i != p.Length; i++)
-            {
-                if (p[i] is X509Name)
-                {
-                    result[pos++] = (X509Name)p[i];
-                }
-            }
-
-            return result;
+			return result.ToArray();
         }
 
 		/**
@@ -279,12 +183,8 @@ namespace Org.BouncyCastle.X509
 		 */
 		public X509Name[] GetEntityNames()
 		{
-			if (holder.EntityName != null)
-			{
-				return GetPrincipals(holder.EntityName);
-			}
-
-			return null;
+			var entityName = m_holder.EntityName;
+			return entityName == null ? null : GetPrincipals(entityName);
 		}
 
 		/**
@@ -294,12 +194,8 @@ namespace Org.BouncyCastle.X509
 		 */
 		public X509Name[] GetIssuer()
 		{
-			if (holder.BaseCertificateID != null)
-			{
-				return GetPrincipals(holder.BaseCertificateID.Issuer);
-			}
-
-			return null;
+			var baseCertificateID = m_holder.BaseCertificateID;
+			return baseCertificateID == null ? null : GetPrincipals(baseCertificateID.Issuer);
 		}
 
 		/**
@@ -307,23 +203,9 @@ namespace Org.BouncyCastle.X509
 		 *
 		 * @return the certificate serial number, null if no BaseCertificateID is set.
 		 */
-		public BigInteger SerialNumber
-		{
-			get
-			{
-				if (holder.BaseCertificateID != null)
-				{
-					return holder.BaseCertificateID.Serial.Value;
-				}
+		public BigInteger SerialNumber => m_holder.BaseCertificateID?.Serial.Value;
 
-				return null;
-			}
-		}
-
-		public object Clone()
-		{
-			return new AttributeCertificateHolder((Asn1Sequence)holder.ToAsn1Object());
-		}
+		public object Clone() => new AttributeCertificateHolder((Asn1Sequence)m_holder.ToAsn1Object());
 
 		public bool Match(X509Certificate x509Cert)
 		{
@@ -332,23 +214,26 @@ namespace Org.BouncyCastle.X509
 
 			try
 			{
-				if (holder.BaseCertificateID != null)
+                var baseCertificateID = m_holder.BaseCertificateID;
+                if (baseCertificateID != null)
 				{
-					return holder.BaseCertificateID.Serial.HasValue(x509Cert.SerialNumber)
-						&& MatchesDN(PrincipalUtilities.GetIssuerX509Principal(x509Cert), holder.BaseCertificateID.Issuer);
+					return baseCertificateID.Serial.HasValue(x509Cert.SerialNumber)
+						&& MatchesDN(x509Cert.IssuerDN, baseCertificateID.Issuer);
 				}
 
-				if (holder.EntityName != null)
+				var entityName = m_holder.EntityName;
+				if (entityName != null)
 				{
-					if (MatchesDN(PrincipalUtilities.GetSubjectX509Principal(x509Cert), holder.EntityName))
+					if (MatchesDN(x509Cert.SubjectDN, entityName))
 						return true;
 				}
 
-				if (holder.ObjectDigestInfo != null)
+				var objectDigestInfo = m_holder.ObjectDigestInfo;
+				if (objectDigestInfo != null)
 				{
 					IDigest md = DigestUtilities.GetDigest(DigestAlgorithm);
 
-					switch (DigestedObjectType)
+					switch (objectDigestInfo.DigestedObjectType.IntValueExact)
 					{
 					case ObjectDigestInfo.PublicKey:
 					{
@@ -363,15 +248,12 @@ namespace Org.BouncyCastle.X509
 						md.BlockUpdate(b, 0, b.Length);
 						break;
 					}
-
 					// TODO Default handler?
 					}
 
 					// TODO Shouldn't this be the other way around?
-					if (!Arrays.AreEqual(DigestUtilities.DoFinal(md), GetObjectDigest()))
-					{
+					if (!Arrays.AreEqual(GetObjectDigest(), DigestUtilities.DoFinal(md)))
 						return false;
-					}
 				}
 			}
 			catch (Exception)
@@ -381,27 +263,13 @@ namespace Org.BouncyCastle.X509
 			return false;
 		}
 
-		public override bool Equals(
-			object obj)
+		public virtual bool Equals(AttributeCertificateHolder other)
 		{
-			if (obj == this)
-			{
-				return true;
-			}
-
-			if (!(obj is AttributeCertificateHolder))
-			{
-				return false;
-			}
-
-			AttributeCertificateHolder other = (AttributeCertificateHolder)obj;
+            return this == other || m_holder.Equals(other?.m_holder);
+        }
 
-			return this.holder.Equals(other.holder);
-		}
+		public override bool Equals(object obj) => Equals(obj as AttributeCertificateHolder);
 
-		public override int GetHashCode()
-		{
-			return this.holder.GetHashCode();
-		}
+		public override int GetHashCode() => m_holder.GetHashCode();
 	}
 }
diff --git a/crypto/src/x509/PrincipalUtil.cs b/crypto/src/x509/PrincipalUtil.cs
index fb1b01b40..22b0fd76e 100644
--- a/crypto/src/x509/PrincipalUtil.cs
+++ b/crypto/src/x509/PrincipalUtil.cs
@@ -1,3 +1,5 @@
+using System;
+
 using Org.BouncyCastle.Asn1.X509;
 
 namespace Org.BouncyCastle.X509
@@ -10,24 +12,16 @@ namespace Org.BouncyCastle.X509
     /// can be.</p>
     /// </remarks>
     // TODO[api] Make static
+    [Obsolete("Will be removed")]
     public class PrincipalUtilities
 	{
 		/// <summary>Return the issuer of the given cert as an X509Principal.</summary>
-		public static X509Name GetIssuerX509Principal(X509Certificate cert)
-		{
-            return cert.TbsCertificate.Issuer;
-		}
+		public static X509Name GetIssuerX509Principal(X509Certificate cert) => cert.IssuerDN;
 
 		/// <summary>Return the subject of the given cert as an X509Principal.</summary>
-		public static X509Name GetSubjectX509Principal(X509Certificate cert)
-		{
-            return cert.TbsCertificate.Subject;
-		}
+		public static X509Name GetSubjectX509Principal(X509Certificate cert) => cert.SubjectDN;
 
 		/// <summary>Return the issuer of the given CRL as an X509Principal.</summary>
-		public static X509Name GetIssuerX509Principal(X509Crl crl)
-		{
-			return crl.CertificateList.TbsCertList.Issuer;
-		}
+		public static X509Name GetIssuerX509Principal(X509Crl crl) => crl.IssuerDN;
 	}
 }
diff --git a/crypto/src/x509/X509Utilities.cs b/crypto/src/x509/X509Utilities.cs
index e7dfeb2c5..cee664370 100644
--- a/crypto/src/x509/X509Utilities.cs
+++ b/crypto/src/x509/X509Utilities.cs
@@ -137,6 +137,22 @@ namespace Org.BouncyCastle.X509
 			return digestResult.Collect();
         }
 
+        internal static byte[] CalculateDigest(IDigestFactory digestFactory, byte[] buf, int off, int len)
+        {
+            var digestCalculator = digestFactory.CreateCalculator();
+            var digestResult = CalculateResult(digestCalculator, buf, off, len);
+            return digestResult.Collect();
+        }
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        internal static byte[] CalculateDigest(IDigestFactory digestFactory, ReadOnlySpan<byte> buf)
+        {
+            var digestCalculator = digestFactory.CreateCalculator();
+            var digestResult = CalculateResult(digestCalculator, buf);
+            return digestResult.Collect();
+        }
+#endif
+
         internal static byte[] CalculateDigest(IDigestFactory digestFactory,
             Asn1Encodable asn1Encodable)
         {
@@ -145,6 +161,28 @@ namespace Org.BouncyCastle.X509
             return digestResult.Collect();
         }
 
+        internal static TResult CalculateResult<TResult>(IStreamCalculator<TResult> streamCalculator, byte[] buf,
+            int off, int len)
+        {
+            using (var stream = streamCalculator.Stream)
+            {
+                stream.Write(buf, off, len);
+            }
+            return streamCalculator.GetResult();
+        }
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        internal static TResult CalculateResult<TResult>(IStreamCalculator<TResult> streamCalculator,
+            ReadOnlySpan<byte> buf)
+        {
+            using (var stream = streamCalculator.Stream)
+            {
+                stream.Write(buf);
+            }
+            return streamCalculator.GetResult();
+        }
+#endif
+
         internal static TResult CalculateResult<TResult>(IStreamCalculator<TResult> streamCalculator,
             Asn1Encodable asn1Encodable)
         {
diff --git a/crypto/src/x509/X509V2AttributeCertificateGenerator.cs b/crypto/src/x509/X509V2AttributeCertificateGenerator.cs
index bbb246273..6e5343fce 100644
--- a/crypto/src/x509/X509V2AttributeCertificateGenerator.cs
+++ b/crypto/src/x509/X509V2AttributeCertificateGenerator.cs
@@ -34,7 +34,7 @@ namespace Org.BouncyCastle.X509
 		public void SetHolder(
 			AttributeCertificateHolder holder)
 		{
-			acInfoGen.SetHolder(holder.holder);
+			acInfoGen.SetHolder(holder.m_holder);
 		}
 
 		/// <summary>Set the issuer.</summary>
diff --git a/crypto/src/x509/X509V3CertificateGenerator.cs b/crypto/src/x509/X509V3CertificateGenerator.cs
index 2df8d5409..229508e67 100644
--- a/crypto/src/x509/X509V3CertificateGenerator.cs
+++ b/crypto/src/x509/X509V3CertificateGenerator.cs
@@ -136,11 +136,20 @@ namespace Org.BouncyCastle.X509
             tbsGen.SetSubjectPublicKeyInfo(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey));
         }
 
-		/// <summary>
-		/// Set the subject unique ID - note: it is very rare that it is correct to do this.
-		/// </summary>
-		/// <param name="uniqueID"/>
-		public void SetSubjectUniqueID(
+        /// <summary>
+        /// Set the SubjectPublicKeyInfo for the public key that this certificate identifies.
+        /// </summary>
+        /// <param name="subjectPublicKeyInfo"/>
+        public void SetSubjectPublicKeyInfo(SubjectPublicKeyInfo subjectPublicKeyInfo)
+        {
+            tbsGen.SetSubjectPublicKeyInfo(subjectPublicKeyInfo);
+        }
+
+        /// <summary>
+        /// Set the subject unique ID - note: it is very rare that it is correct to do this.
+        /// </summary>
+        /// <param name="uniqueID"/>
+        public void SetSubjectUniqueID(
 			bool[] uniqueID)
 		{
 			tbsGen.SetSubjectUniqueID(BooleanToBitString(uniqueID));
@@ -157,15 +166,6 @@ namespace Org.BouncyCastle.X509
 		}
 
         /// <summary>
-        /// Set the SubjectPublicKeyInfo for the public key that this certificate identifies.
-        /// </summary>
-        /// <param name="subjectPublicKeyInfo"/>
-        public void SetSubjectPublicKeyInfo(SubjectPublicKeyInfo subjectPublicKeyInfo)
-        {
-            tbsGen.SetSubjectPublicKeyInfo(subjectPublicKeyInfo);
-        }
-
-        /// <summary>
         /// Add a given extension field for the standard extensions tag (tag 3).
         /// </summary>
         /// <param name="oid">string containing a dotted decimal Object Identifier.</param>
diff --git a/crypto/src/x509/extension/AuthorityKeyIdentifierStructure.cs b/crypto/src/x509/extension/AuthorityKeyIdentifierStructure.cs
index 006dc009b..abd6bb7cc 100644
--- a/crypto/src/x509/extension/AuthorityKeyIdentifierStructure.cs
+++ b/crypto/src/x509/extension/AuthorityKeyIdentifierStructure.cs
@@ -25,13 +25,11 @@ namespace Org.BouncyCastle.X509.Extension
 		{
 		}
 
-		private static Asn1Sequence FromCertificate(
-			X509Certificate certificate)
+		private static Asn1Sequence FromCertificate(X509Certificate certificate)
 		{
 			try
 			{
-				GeneralName genName = new GeneralName(
-					PrincipalUtilities.GetIssuerX509Principal(certificate));
+				GeneralName genName = new GeneralName(certificate.IssuerDN);
 
 				if (certificate.Version == 3)
 				{
diff --git a/crypto/test/src/cms/test/EnvelopedDataStreamTest.cs b/crypto/test/src/cms/test/EnvelopedDataStreamTest.cs
index 365d0e671..0962d5bea 100644
--- a/crypto/test/src/cms/test/EnvelopedDataStreamTest.cs
+++ b/crypto/test/src/cms/test/EnvelopedDataStreamTest.cs
@@ -497,7 +497,7 @@ namespace Org.BouncyCastle.Cms.Tests
 
 				var recSel = new RecipientID
 				{
-                    Issuer = PrincipalUtilities.GetIssuerX509Principal(ReciECCert),
+                    Issuer = ReciECCert.IssuerDN,
 					SerialNumber = ReciECCert.SerialNumber
 	            };
 
diff --git a/crypto/test/src/cms/test/EnvelopedDataTest.cs b/crypto/test/src/cms/test/EnvelopedDataTest.cs
index 1c5d1c953..02c76a0c1 100644
--- a/crypto/test/src/cms/test/EnvelopedDataTest.cs
+++ b/crypto/test/src/cms/test/EnvelopedDataTest.cs
@@ -910,7 +910,7 @@ namespace Org.BouncyCastle.Cms.Tests
 			byte[] expectedData, X509Certificate reciCert, AsymmetricKeyParameter reciPrivKey)
 		{
 			RecipientID rid = new RecipientID();
-			rid.Issuer = PrincipalUtilities.GetIssuerX509Principal(reciCert);
+			rid.Issuer = reciCert.IssuerDN;
 			rid.SerialNumber = reciCert.SerialNumber;
 
 			RecipientInformation recipient = recipients[rid];
diff --git a/crypto/test/src/ocsp/test/OCSPTest.cs b/crypto/test/src/ocsp/test/OCSPTest.cs
index 73e2ff9f7..7b2e44781 100644
--- a/crypto/test/src/ocsp/test/OCSPTest.cs
+++ b/crypto/test/src/ocsp/test/OCSPTest.cs
@@ -221,7 +221,7 @@ namespace Org.BouncyCastle.Ocsp.Tests
 			//
 			// general id value for our test issuer cert and a serial number.
 			//
-			CertificateID id = new CertificateID(CertificateID.HashSha1, testCert, BigInteger.One);
+			CertificateID id = new CertificateID(CertificateID.DigestSha1, testCert, BigInteger.One);
 
 			//
 			// basic request generation
@@ -260,7 +260,7 @@ namespace Org.BouncyCastle.Ocsp.Tests
 
 			gen.SetRequestorName(new GeneralName(GeneralName.DirectoryName, new X509Name("CN=fred")));
 
-			gen.AddRequest(new CertificateID(CertificateID.HashSha1, testCert, BigInteger.One));
+			gen.AddRequest(new CertificateID(CertificateID.DigestSha1, testCert, BigInteger.One));
 
 			chain[0] = testCert;
 
@@ -328,7 +328,7 @@ namespace Org.BouncyCastle.Ocsp.Tests
 
 			gen.SetRequestExtensions(new X509Extensions(oids, values));
 
-			gen.AddRequest(new CertificateID(CertificateID.HashSha1, testCert, BigInteger.One));
+			gen.AddRequest(new CertificateID(CertificateID.DigestSha1, testCert, BigInteger.One));
 
 			chain[0] = testCert;
 
@@ -407,7 +407,7 @@ namespace Org.BouncyCastle.Ocsp.Tests
 			//
 			// general id value for our test issuer cert and a serial number.
 			//
-			CertificateID id = new CertificateID(CertificateID.HashSha1, testCert, BigInteger.One);
+			CertificateID id = new CertificateID(CertificateID.DigestSha1, testCert, BigInteger.One);
 
 			//
 			// basic request generation
@@ -415,7 +415,7 @@ namespace Org.BouncyCastle.Ocsp.Tests
 			OcspReqGenerator gen = new OcspReqGenerator();
 
 			gen.AddRequest(
-				new CertificateID(CertificateID.HashSha1, testCert, BigInteger.One));
+				new CertificateID(CertificateID.DigestSha1, testCert, BigInteger.One));
 
 			OcspReq req = gen.Generate();
 
@@ -448,7 +448,7 @@ namespace Org.BouncyCastle.Ocsp.Tests
 			gen.SetRequestorName(new GeneralName(GeneralName.DirectoryName, new X509Name("CN=fred")));
 
 			gen.AddRequest(
-				new CertificateID(CertificateID.HashSha1, testCert, BigInteger.One));
+				new CertificateID(CertificateID.DigestSha1, testCert, BigInteger.One));
 
 			chain[0] = testCert;
 
@@ -517,7 +517,7 @@ namespace Org.BouncyCastle.Ocsp.Tests
 			gen.SetRequestExtensions(new X509Extensions(oids, values));
 
 			gen.AddRequest(
-				new CertificateID(CertificateID.HashSha1, testCert, BigInteger.One));
+				new CertificateID(CertificateID.DigestSha1, testCert, BigInteger.One));
 
 			chain[0] = testCert;
 
@@ -609,7 +609,7 @@ namespace Org.BouncyCastle.Ocsp.Tests
 			//
 			// general id value for our test issuer cert and a serial number.
 			//
-			CertificateID   id = new CertificateID(CertificateID.HashSha1, testCert, BigInteger.One);
+			CertificateID   id = new CertificateID(CertificateID.DigestSha1, testCert, BigInteger.One);
 
 			//
 			// basic request generation
@@ -617,7 +617,7 @@ namespace Org.BouncyCastle.Ocsp.Tests
 			OcspReqGenerator gen = new OcspReqGenerator();
 
 			gen.AddRequest(
-				new CertificateID(CertificateID.HashSha1, testCert, BigInteger.One));
+				new CertificateID(CertificateID.DigestSha1, testCert, BigInteger.One));
 
 			OcspReq req = gen.Generate();
 
@@ -650,7 +650,7 @@ namespace Org.BouncyCastle.Ocsp.Tests
 			gen.SetRequestorName(new GeneralName(GeneralName.DirectoryName, new X509Name("CN=fred")));
 
 			gen.AddRequest(
-				new CertificateID(CertificateID.HashSha1, testCert, BigInteger.One));
+				new CertificateID(CertificateID.DigestSha1, testCert, BigInteger.One));
 
 			chain[0] = testCert;
 
@@ -719,7 +719,7 @@ namespace Org.BouncyCastle.Ocsp.Tests
 			gen.SetRequestExtensions(new X509Extensions(oids, values));
 
 			gen.AddRequest(
-				new CertificateID(CertificateID.HashSha1, testCert, BigInteger.One));
+				new CertificateID(CertificateID.DigestSha1, testCert, BigInteger.One));
 
 			chain[0] = testCert;
 
diff --git a/crypto/test/src/test/AttrCertSelectorTest.cs b/crypto/test/src/test/AttrCertSelectorTest.cs
index 1e82f810c..664d2c2fc 100644
--- a/crypto/test/src/test/AttrCertSelectorTest.cs
+++ b/crypto/test/src/test/AttrCertSelectorTest.cs
@@ -105,7 +105,7 @@ namespace Org.BouncyCastle.Tests
 				new DerSequence(roleSyntax));
 
 			gen.AddAttribute(attributes);
-			gen.SetHolder(new AttributeCertificateHolder(PrincipalUtilities.GetSubjectX509Principal(iCert)));
+			gen.SetHolder(new AttributeCertificateHolder(iCert.SubjectDN));
 			gen.SetIssuer(new AttributeCertificateIssuer(new X509Name("cn=test")));
 			gen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50));
 			gen.SetNotAfter(DateTime.UtcNow.AddSeconds(50));
diff --git a/crypto/test/src/test/TestUtilities.cs b/crypto/test/src/test/TestUtilities.cs
index be983637c..7a94288a9 100644
--- a/crypto/test/src/test/TestUtilities.cs
+++ b/crypto/test/src/test/TestUtilities.cs
@@ -53,7 +53,7 @@ namespace Org.BouncyCastle.Tests
 			X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
 
 			certGen.SetSerialNumber(BigInteger.One);
-			certGen.SetIssuerDN(PrincipalUtilities.GetSubjectX509Principal(caCert));
+			certGen.SetIssuerDN(caCert.SubjectDN);
 			certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50));
 			certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50));
 			certGen.SetSubjectDN(new X509Name("CN=Test Intermediate Certificate"));
@@ -75,7 +75,7 @@ namespace Org.BouncyCastle.Tests
 			X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
 
 			certGen.SetSerialNumber(BigInteger.One);
-			certGen.SetIssuerDN(PrincipalUtilities.GetSubjectX509Principal(caCert));
+			certGen.SetIssuerDN(caCert.SubjectDN);
 			certGen.SetNotBefore(DateTime.UtcNow.AddSeconds(-50));
 			certGen.SetNotAfter(DateTime.UtcNow.AddSeconds(50));
 			certGen.SetSubjectDN(new X509Name("CN=Test End Certificate"));
@@ -97,7 +97,7 @@ namespace Org.BouncyCastle.Tests
 			X509V2CrlGenerator	crlGen = new X509V2CrlGenerator();
 			DateTime			now = DateTime.UtcNow;
 
-			crlGen.SetIssuerDN(PrincipalUtilities.GetSubjectX509Principal(caCert));
+			crlGen.SetIssuerDN(caCert.SubjectDN);
 
 			crlGen.SetThisUpdate(now);
 			crlGen.SetNextUpdate(now.AddSeconds(100));
diff --git a/crypto/test/src/test/X509StoreTest.cs b/crypto/test/src/test/X509StoreTest.cs
index 2a8d44424..5ce46d0dc 100644
--- a/crypto/test/src/test/X509StoreTest.cs
+++ b/crypto/test/src/test/X509StoreTest.cs
@@ -81,7 +81,7 @@ namespace Org.BouncyCastle.Tests
 			// Searching for rootCert by subjectDN
 
 			X509CertStoreSelector targetConstraints = new X509CertStoreSelector();
-			targetConstraints.Subject = PrincipalUtilities.GetSubjectX509Principal(rootCert);
+			targetConstraints.Subject = rootCert.SubjectDN;
 			var certs = new List<X509Certificate>(certStore.EnumerateMatches(targetConstraints));
 			if (certs.Count != 1 || !certs.Contains(rootCert))
 			{
@@ -90,7 +90,7 @@ namespace Org.BouncyCastle.Tests
 
 			// Searching for rootCert by subjectDN encoded as byte
 			targetConstraints = new X509CertStoreSelector();
-			targetConstraints.Subject = PrincipalUtilities.GetSubjectX509Principal(rootCert);
+			targetConstraints.Subject = rootCert.SubjectDN;
 			certs = new List<X509Certificate>(certStore.EnumerateMatches(targetConstraints));
 			if (certs.Count != 1 || !certs.Contains(rootCert))
 			{
@@ -111,7 +111,7 @@ namespace Org.BouncyCastle.Tests
 
 			// Searching for interCert by issuerDN
 			targetConstraints = new X509CertStoreSelector();
-			targetConstraints.Issuer = PrincipalUtilities.GetSubjectX509Principal(rootCert);
+			targetConstraints.Issuer = rootCert.SubjectDN;
 			certs = new List<X509Certificate>(certStore.EnumerateMatches(targetConstraints));
 			if (certs.Count != 2)
 			{