<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.0" />

DigestAlgorithmsBuilder

using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Operators.Utilities; using Org.BouncyCastle.X509; using System; using System.Collections.Generic; namespace Org.BouncyCastle.Cms { internal class DigestAlgorithmsBuilder { private struct UniqueAlgID : IEquatable<UniqueAlgID> { private readonly AlgorithmIdentifier m_algID; private readonly int m_hashCode; internal AlgorithmIdentifier AlgID => m_algID; internal UniqueAlgID(AlgorithmIdentifier algID) { if (algID == null) throw new ArgumentNullException("algID"); m_algID = algID; m_hashCode = CalculateHashCode(algID); } public override bool Equals(object obj) { if (obj is UniqueAlgID) { UniqueAlgID other = (UniqueAlgID)obj; return Equivalent(other); } return false; } public override int GetHashCode() { return m_hashCode; } bool IEquatable<UniqueAlgID>.Equals(UniqueAlgID other) { return Equivalent(other); } private static int CalculateHashCode(AlgorithmIdentifier algID) { if (X509Utilities.HasAbsentParameters(algID)) return algID.Algorithm.GetHashCode(); return algID.GetHashCode(); } private bool Equivalent(UniqueAlgID other) { if (m_hashCode == other.m_hashCode) return X509Utilities.AreEquivalentAlgorithms(m_algID, other.m_algID); return false; } } private readonly List<AlgorithmIdentifier> m_ordered = new List<AlgorithmIdentifier>(); private readonly HashSet<UniqueAlgID> m_unique = new HashSet<UniqueAlgID>(); private readonly IDigestAlgorithmFinder m_digestAlgorithmFinder; internal DigestAlgorithmsBuilder(IDigestAlgorithmFinder digestAlgorithmFinder) { m_digestAlgorithmFinder = digestAlgorithmFinder; } internal bool Add(AlgorithmIdentifier algID) { if (algID == null) throw new ArgumentNullException("algID"); return ImplAdd(GetCanonical(algID)); } internal bool AddExisting(AlgorithmIdentifier algID) { if (algID == null) throw new ArgumentNullException("algID"); return ImplAdd(algID); } internal void AddExisting(IEnumerable<AlgorithmIdentifier> algIDs) { if (algIDs == null) throw new ArgumentNullException("algIDs"); foreach (AlgorithmIdentifier algID in algIDs) { AddExisting(algID); } } internal Asn1Set Build(bool useDL) { return m_ordered.ToAsn1Set(false, useDL); } internal bool Contains(AlgorithmIdentifier algID) { return m_unique.Contains(new UniqueAlgID(algID)); } private bool ImplAdd(AlgorithmIdentifier algID) { bool num = m_unique.Add(new UniqueAlgID(algID)); if (num) m_ordered.Add(algID); return num; } private AlgorithmIdentifier GetCanonical(AlgorithmIdentifier algID) { if (!X509Utilities.HasAbsentParameters(algID)) return algID; return m_digestAlgorithmFinder.Find(algID.Algorithm); } } }