فهرست منبع

move OidComparers to seperate unit

Ugochukwu Mmaduekwe 1 هفته پیش
والد
کامیت
bba315d9c0

+ 1 - 0
CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr

@@ -34,6 +34,7 @@ uses
   ClpArrayUtilities in '..\..\CryptoLib\src\GeneralUtilities\ClpArrayUtilities.pas',
   ClpAsn1DigestFactory in '..\..\CryptoLib\src\Crypto\Operators\ClpAsn1DigestFactory.pas',
   ClpAsn1Dumper in '..\..\CryptoLib\src\Asn1\ClpAsn1Dumper.pas',
+  ClpAsn1Comparers in '..\..\CryptoLib\src\Asn1\ClpAsn1Comparers.pas',
   ClpAsn1Objects in '..\..\CryptoLib\src\Asn1\ClpAsn1Objects.pas',
   ClpAsn1SignatureFactory in '..\..\CryptoLib\src\Crypto\Operators\ClpAsn1SignatureFactory.pas',
   ClpAsn1Streams in '..\..\CryptoLib\src\Asn1\ClpAsn1Streams.pas',

+ 2 - 2
CryptoLib.Tests/src/Others/CertTests.pas

@@ -83,7 +83,7 @@ uses
   ClpIAsn1Core,
   ClpAsn1Objects,
   ClpCryptoLibTypes,
-  ClpCryptoLibComparers,
+  ClpAsn1Comparers,
   ClpPkcsObjectIdentifiers,
   ClpPkcsAsn1Objects,
   ClpIPkcsAsn1Objects,
@@ -447,7 +447,7 @@ var
   LAttrs: TDictionary<IDerObjectIdentifier, String>;
   LOrd: TList<IDerObjectIdentifier>;
 begin
-  LAttrs := TDictionary<IDerObjectIdentifier, String>.Create(TCryptoLibComparers.OidEqualityComparer);
+  LAttrs := TDictionary<IDerObjectIdentifier, String>.Create(TAsn1Comparers.OidEqualityComparer);
   LOrd := TList<IDerObjectIdentifier>.Create;
   try
     LAttrs.Add(TX509Name.C, 'AU');

+ 3 - 3
CryptoLib.Tests/src/X509/X509CertGenTests.pas

@@ -69,7 +69,7 @@ uses
   ClpDigestUtilities,
   ClpIAsn1Objects,
   ClpCryptoLibTypes,
-  ClpCryptoLibComparers,
+  ClpAsn1Comparers,
   CryptoLibTestBase;
 
 type
@@ -174,8 +174,8 @@ var
   LAttrs: TDictionary<IDerObjectIdentifier, String>;
   LOrd: TList<IDerObjectIdentifier>;
 begin
-  LAttrs := TDictionary<IDerObjectIdentifier, String>.Create(TCryptoLibComparers.OidEqualityComparer);
-  LOrd := TList<IDerObjectIdentifier>.Create(TCryptoLibComparers.OidComparer);
+  LAttrs := TDictionary<IDerObjectIdentifier, String>.Create(TAsn1Comparers.OidEqualityComparer);
+  LOrd := TList<IDerObjectIdentifier>.Create(TAsn1Comparers.OidComparer);
   try
     LAttrs.Add(TX509Name.C, 'NG');
     LAttrs.Add(TX509Name.O, 'CryptoLib4Pascal');

+ 152 - 0
CryptoLib/src/Asn1/ClpAsn1Comparers.pas

@@ -0,0 +1,152 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
+{ *                 Github Repository <https://github.com/Xor-el>                   * }
+
+{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
+{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
+
+{ *                              Acknowledgements:                                  * }
+{ *                                                                                 * }
+{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
+{ *                           development of this library                           * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpAsn1Comparers;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  Generics.Defaults,
+  ClpIAsn1Objects;
+
+type
+  /// <summary>
+  /// Equality comparer for IDerObjectIdentifier that uses value-based comparison
+  /// (Asn1Equals) instead of reference equality. Used with TDictionary.
+  /// </summary>
+  TOidEqualityComparer = class(TInterfacedObject, IEqualityComparer<IDerObjectIdentifier>)
+  strict private
+    function Equals(const ALeft, ARight: IDerObjectIdentifier): Boolean; reintroduce;
+    function GetHashCode(const AValue: IDerObjectIdentifier): Integer;
+  end;
+
+  /// <summary>
+  /// Comparer for IDerObjectIdentifier that uses value-based comparison
+  /// (Asn1Equals) for equality and ID string comparison for ordering.
+  /// Used with TList to ensure Contains, IndexOf, and Remove work correctly.
+  /// </summary>
+  TOidComparer = class(TInterfacedObject, IComparer<IDerObjectIdentifier>)
+  strict private
+    function Compare(const ALeft, ARight: IDerObjectIdentifier): Integer;
+  end;
+
+  /// <summary>
+  /// Static utility class providing ASN.1-related comparers (e.g. OID).
+  /// </summary>
+  TAsn1Comparers = class sealed(TObject)
+  strict private
+    class var
+      FOidEqualityComparer: IEqualityComparer<IDerObjectIdentifier>;
+      FOidComparer: IComparer<IDerObjectIdentifier>;
+    class constructor Create;
+  public
+    /// <summary>
+    /// Gets the OID equality comparer for use with TDictionary.
+    /// </summary>
+    class property OidEqualityComparer: IEqualityComparer<IDerObjectIdentifier> read FOidEqualityComparer;
+
+    /// <summary>
+    /// Gets the OID comparer for use with TList.
+    /// </summary>
+    class property OidComparer: IComparer<IDerObjectIdentifier> read FOidComparer;
+  end;
+
+implementation
+
+{ TOidEqualityComparer }
+
+function TOidEqualityComparer.Equals(const ALeft, ARight: IDerObjectIdentifier): Boolean;
+begin
+  if ALeft = ARight then
+  begin
+    Result := True;
+    Exit;
+  end;
+
+  if (ALeft = nil) or (ARight = nil) then
+  begin
+    Result := False;
+    Exit;
+  end;
+
+  Result := ALeft.Equals(ARight);
+end;
+
+function TOidEqualityComparer.GetHashCode(const AValue: IDerObjectIdentifier): Integer;
+begin
+  if AValue = nil then
+  begin
+    Result := 0;
+    Exit;
+  end;
+
+  Result := AValue.CallAsn1GetHashCode();
+end;
+
+{ TOidComparer }
+
+function TOidComparer.Compare(const ALeft, ARight: IDerObjectIdentifier): Integer;
+begin
+  if (ALeft = nil) and (ARight = nil) then
+  begin
+    Result := 0;
+    Exit;
+  end;
+
+  if ALeft = nil then
+  begin
+    Result := -1;
+    Exit;
+  end;
+
+  if ARight = nil then
+  begin
+    Result := 1;
+    Exit;
+  end;
+
+  if ALeft = ARight then
+  begin
+    Result := 0;
+    Exit;
+  end;
+
+  if ALeft.Equals(ARight) then
+  begin
+    Result := 0;
+    Exit;
+  end;
+
+  if ALeft.Id < ARight.Id then
+    Result := -1
+  else if ALeft.Id > ARight.Id then
+    Result := 1
+  else
+    Result := 0;
+end;
+
+{ TAsn1Comparers }
+
+class constructor TAsn1Comparers.Create;
+begin
+  FOidEqualityComparer := TOidEqualityComparer.Create();
+  FOidComparer := TOidComparer.Create();
+end;
+
+end.

+ 2 - 1
CryptoLib/src/Asn1/Nist/ClpNistNamedCurves.pas

@@ -24,6 +24,7 @@ interface
 uses
   SysUtils,
   Generics.Collections,
+  ClpAsn1Comparers,
   ClpCryptoLibComparers,
   ClpIX9ECAsn1Objects,
   ClpSecNamedCurves,
@@ -146,7 +147,7 @@ end;
 class procedure TNistNamedCurves.Boot;
 begin
   FobjIds := TDictionary<String, IDerObjectIdentifier>.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
-  Fnames := TDictionary<IDerObjectIdentifier, String>.Create(TCryptoLibComparers.OidEqualityComparer);
+  Fnames := TDictionary<IDerObjectIdentifier, String>.Create(TAsn1Comparers.OidEqualityComparer);
 
   DefineCurveAlias('B-163', TSecObjectIdentifiers.SecT163r2);
   DefineCurveAlias('B-233', TSecObjectIdentifiers.SecT233r1);

+ 3 - 2
CryptoLib/src/Asn1/Sec/ClpSecNamedCurves.pas

@@ -24,6 +24,7 @@ interface
 uses
   SysUtils,
   Generics.Collections,
+  ClpAsn1Comparers,
   ClpCryptoLibComparers,
   ClpEncoders,
   ClpGlvTypeBParameters,
@@ -844,8 +845,8 @@ end;
 class procedure TSecNamedCurves.Boot;
 begin
   FobjIds := TDictionary<String, IDerObjectIdentifier>.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
-  Fnames := TDictionary<IDerObjectIdentifier, String>.Create(TCryptoLibComparers.OidEqualityComparer);
-  Fcurves := TDictionary<IDerObjectIdentifier, IX9ECParametersHolder>.Create(TCryptoLibComparers.OidEqualityComparer);
+  Fnames := TDictionary<IDerObjectIdentifier, String>.Create(TAsn1Comparers.OidEqualityComparer);
+  Fcurves := TDictionary<IDerObjectIdentifier, IX9ECParametersHolder>.Create(TAsn1Comparers.OidEqualityComparer);
 
   DefineCurve('secp112r1', TSecObjectIdentifiers.SecP112r1,
     TSecp112r1Holder.Instance);

+ 3 - 2
CryptoLib/src/Asn1/TeleTrust/ClpTeleTrusTNamedCurves.pas

@@ -24,6 +24,7 @@ interface
 uses
   SysUtils,
   Generics.Collections,
+  ClpAsn1Comparers,
   ClpCryptoLibComparers,
   ClpEncoders,
   ClpTeleTrusTObjectIdentifiers,
@@ -418,8 +419,8 @@ end;
 class procedure TTeleTrusTNamedCurves.Boot;
 begin
   FobjIds := TDictionary<String, IDerObjectIdentifier>.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
-  Fnames := TDictionary<IDerObjectIdentifier, String>.Create(TCryptoLibComparers.OidEqualityComparer);
-  Fcurves := TDictionary<IDerObjectIdentifier, IX9ECParametersHolder>.Create(TCryptoLibComparers.OidEqualityComparer);
+  Fnames := TDictionary<IDerObjectIdentifier, String>.Create(TAsn1Comparers.OidEqualityComparer);
+  Fcurves := TDictionary<IDerObjectIdentifier, IX9ECParametersHolder>.Create(TAsn1Comparers.OidEqualityComparer);
 
   DefineCurve('brainpoolP160r1', TTeleTrusTObjectIdentifiers.BrainpoolP160R1,
     TBrainpoolP160r1Holder.Instance);

+ 4 - 3
CryptoLib/src/Asn1/X509/ClpX509Asn1Generators.pas

@@ -34,6 +34,7 @@ uses
   ClpX509Extension,
   ClpRfc5280Asn1Utilities,
   ClpCryptoLibTypes,
+  ClpAsn1Comparers,
   ClpCryptoLibComparers,
   ClpIX509Asn1Generators;
 
@@ -690,7 +691,7 @@ end;
 
 class procedure TX509ExtensionsGenerator.Boot;
 begin
-  FDupsAllowed := TDictionary<IDerObjectIdentifier, Boolean>.Create(TCryptoLibComparers.OidEqualityComparer);
+  FDupsAllowed := TDictionary<IDerObjectIdentifier, Boolean>.Create(TAsn1Comparers.OidEqualityComparer);
   // OIDs that allow duplicate extensions
   FDupsAllowed.Add(TX509Extensions.SubjectAlternativeName, True);
   FDupsAllowed.Add(TX509Extensions.IssuerAlternativeName, True);
@@ -701,8 +702,8 @@ end;
 constructor TX509ExtensionsGenerator.Create;
 begin
   inherited Create();
-  FExtensions := TDictionary<IDerObjectIdentifier, IX509Extension>.Create(TCryptoLibComparers.OidEqualityComparer);
-  FOrdering := TList<IDerObjectIdentifier>.Create(TCryptoLibComparers.OidComparer);
+  FExtensions := TDictionary<IDerObjectIdentifier, IX509Extension>.Create(TAsn1Comparers.OidEqualityComparer);
+  FOrdering := TList<IDerObjectIdentifier>.Create(TAsn1Comparers.OidComparer);
 end;
 
 destructor TX509ExtensionsGenerator.Destroy;

+ 17 - 16
CryptoLib/src/Asn1/X509/ClpX509Asn1Objects.pas

@@ -52,6 +52,7 @@ uses
   ClpDateTimeUtilities,
   ClpIetfUtilities,
   ClpEncoders,
+  ClpAsn1Comparers,
   ClpCryptoLibComparers;
 
 resourcestring
@@ -5061,7 +5062,7 @@ var
 begin
   inherited Create();
   FSeq := ASeq;
-  FUsageTable := TDictionary<IDerObjectIdentifier, Boolean>.Create(TCryptoLibComparers.OidEqualityComparer);
+  FUsageTable := TDictionary<IDerObjectIdentifier, Boolean>.Create(TAsn1Comparers.OidEqualityComparer);
 
   for I := 0 to ASeq.Count - 1 do
   begin
@@ -5077,7 +5078,7 @@ var
   LOid: IDerObjectIdentifier;
 begin
   inherited Create();
-  FUsageTable := TDictionary<IDerObjectIdentifier, Boolean>.Create(TCryptoLibComparers.OidEqualityComparer);
+  FUsageTable := TDictionary<IDerObjectIdentifier, Boolean>.Create(TAsn1Comparers.OidEqualityComparer);
   LV := TAsn1EncodableVector.Create();
 
   for I := 0 to System.Length(AUsages) - 1 do
@@ -5097,7 +5098,7 @@ var
   LElements: TCryptoLibGenericArray<IAsn1Encodable>;
 begin
   inherited Create();
-  FUsageTable := TDictionary<IDerObjectIdentifier, Boolean>.Create(TCryptoLibComparers.OidEqualityComparer);
+  FUsageTable := TDictionary<IDerObjectIdentifier, Boolean>.Create(TAsn1Comparers.OidEqualityComparer);
 
   LCount := High(AUsages) - Low(AUsages) + 1;
   System.SetLength(LElements, LCount);
@@ -5520,8 +5521,8 @@ var
 begin
   inherited Create();
 
-  FOrdering := TList<IDerObjectIdentifier>.Create(TCryptoLibComparers.OidComparer);
-  FExtensions := TDictionary<IDerObjectIdentifier, IX509Extension>.Create(TCryptoLibComparers.OidEqualityComparer);
+  FOrdering := TList<IDerObjectIdentifier>.Create(TAsn1Comparers.OidComparer);
+  FExtensions := TDictionary<IDerObjectIdentifier, IX509Extension>.Create(TAsn1Comparers.OidEqualityComparer);
 
   // Don't require non-empty sequence; we see empty extension blocks in the wild
   for I := 0 to ASeq.Count - 1 do
@@ -5560,7 +5561,7 @@ begin
 
   if AOrdering = nil then
   begin
-    FOrdering := TList<IDerObjectIdentifier>.Create(TCryptoLibComparers.OidComparer);
+    FOrdering := TList<IDerObjectIdentifier>.Create(TAsn1Comparers.OidComparer);
     for LOid in AExtensions.Keys do
     begin
       FOrdering.Add(LOid);
@@ -5568,11 +5569,11 @@ begin
   end
   else
   begin
-    FOrdering := TList<IDerObjectIdentifier>.Create(TCryptoLibComparers.OidComparer);
+    FOrdering := TList<IDerObjectIdentifier>.Create(TAsn1Comparers.OidComparer);
     FOrdering.AddRange(AOrdering);
   end;
 
-  FExtensions := TDictionary<IDerObjectIdentifier, IX509Extension>.Create(TCryptoLibComparers.OidEqualityComparer);
+  FExtensions := TDictionary<IDerObjectIdentifier, IX509Extension>.Create(TAsn1Comparers.OidEqualityComparer);
   for LOid in FOrdering do
   begin
     FExtensions.Add(LOid, AExtensions[LOid]);
@@ -5586,9 +5587,9 @@ var
 begin
   inherited Create();
 
-  FOrdering := TList<IDerObjectIdentifier>.Create(TCryptoLibComparers.OidComparer);
+  FOrdering := TList<IDerObjectIdentifier>.Create(TAsn1Comparers.OidComparer);
   FOrdering.AddRange(AOids);
-  FExtensions := TDictionary<IDerObjectIdentifier, IX509Extension>.Create(TCryptoLibComparers.OidEqualityComparer);
+  FExtensions := TDictionary<IDerObjectIdentifier, IX509Extension>.Create(TAsn1Comparers.OidEqualityComparer);
 
   I := 0;
   for I := 0 to FOrdering.Count - 1 do
@@ -5866,7 +5867,7 @@ begin
   FSeq := ASeq;
   FConverter := nil;
 
-  LOidList := TList<IDerObjectIdentifier>.Create(TCryptoLibComparers.OidComparer);
+  LOidList := TList<IDerObjectIdentifier>.Create(TAsn1Comparers.OidComparer);
   LValueList := TList<String>.Create();
   LAddedList := TList<Boolean>.Create();
   try
@@ -6079,7 +6080,7 @@ begin
   inherited Create();
   FConverter := AConverter;
 
-  LOidList := TList<IDerObjectIdentifier>.Create(TCryptoLibComparers.OidComparer);
+  LOidList := TList<IDerObjectIdentifier>.Create(TAsn1Comparers.OidComparer);
   LValueList := TList<String>.Create();
   LAddedList := TList<Boolean>.Create();
   try
@@ -6100,7 +6101,7 @@ begin
     if AReverse then
     begin
       // Reverse the order
-      LO := TList<IDerObjectIdentifier>.Create(TCryptoLibComparers.OidComparer);
+      LO := TList<IDerObjectIdentifier>.Create(TAsn1Comparers.OidComparer);
       LV := TList<String>.Create();
       LA := TList<Boolean>.Create();
       try
@@ -6367,9 +6368,9 @@ end;
 class procedure TX509Name.Boot;
 begin
   FDefaultReverse := False;
-  FDefaultSymbols := TDictionary<IDerObjectIdentifier, String>.Create(TCryptoLibComparers.OidEqualityComparer);
-  FRFC2253Symbols := TDictionary<IDerObjectIdentifier, String>.Create(TCryptoLibComparers.OidEqualityComparer);
-  FRFC1779Symbols := TDictionary<IDerObjectIdentifier, String>.Create(TCryptoLibComparers.OidEqualityComparer);
+  FDefaultSymbols := TDictionary<IDerObjectIdentifier, String>.Create(TAsn1Comparers.OidEqualityComparer);
+  FRFC2253Symbols := TDictionary<IDerObjectIdentifier, String>.Create(TAsn1Comparers.OidEqualityComparer);
+  FRFC1779Symbols := TDictionary<IDerObjectIdentifier, String>.Create(TAsn1Comparers.OidEqualityComparer);
   FDefaultLookup := TDictionary<String, IDerObjectIdentifier>.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
 
   // OID constants

+ 2 - 1
CryptoLib/src/Asn1/X509/ClpX509SignatureUtilities.pas

@@ -45,6 +45,7 @@ uses
   ClpX509ObjectIdentifiers,
   ClpSignerUtilities,
   ClpX509Utilities,
+  ClpAsn1Comparers,
   ClpCryptoLibComparers,
   ClpCryptoLibTypes;
 
@@ -98,7 +99,7 @@ var
 begin
   FAlgorithms := TDictionary<String, IDerObjectIdentifier>.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
   FExParams := TDictionary<String, IAsn1Encodable>.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
-  FNoParams := TDictionary<IDerObjectIdentifier, IAlgorithmIdentifier>.Create(TCryptoLibComparers.OidEqualityComparer);
+  FNoParams := TDictionary<IDerObjectIdentifier, IAlgorithmIdentifier>.Create(TAsn1Comparers.OidEqualityComparer);
 
   // MD2 algorithms
   FAlgorithms.Add('MD2WITHRSAENCRYPTION', TPkcsObjectIdentifiers.MD2WithRsaEncryption);

+ 2 - 1
CryptoLib/src/Crypto/Agreements/ClpAgreementUtilities.pas

@@ -26,6 +26,7 @@ uses
   Generics.Collections,
   ClpAsn1Objects,
   ClpCollectionUtilities,
+  ClpAsn1Comparers,
   ClpCryptoLibComparers,
   ClpCryptoLibTypes,
   ClpDHBasicAgreement,
@@ -90,7 +91,7 @@ begin
   FAlgorithmMap.Add('DIFFIEHELLMAN', 'DH');
   FAlgorithmMap.Add('ECCDH', 'ECDHC');
 
-  FAlgorithmOidMap := TDictionary<IDerObjectIdentifier, String>.Create(TCryptoLibComparers.OidEqualityComparer);
+  FAlgorithmOidMap := TDictionary<IDerObjectIdentifier, String>.Create(TAsn1Comparers.OidEqualityComparer);
   FAlgorithmOidMap.AddOrSetValue(TEdECObjectIdentifiers.IdX25519, 'X25519');
 end;
 

+ 2 - 1
CryptoLib/src/Crypto/Ciphers/ClpCipherUtilities.pas

@@ -27,6 +27,7 @@ uses
   Generics.Collections,
   ClpAsn1Objects,
   ClpCollectionUtilities,
+  ClpAsn1Comparers,
   ClpCryptoLibComparers,
   ClpCryptoLibTypes,
   ClpDigestUtilities,
@@ -170,7 +171,7 @@ implementation
 class procedure TCipherUtilities.Boot;
 begin
   FAlgorithmMap := TDictionary<String, String>.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
-  FAlgorithmOidMap := TDictionary<IDerObjectIdentifier, String>.Create(TCryptoLibComparers.OidEqualityComparer);
+  FAlgorithmOidMap := TDictionary<IDerObjectIdentifier, String>.Create(TAsn1Comparers.OidEqualityComparer);
 
   TNistObjectIdentifiers.Boot;
   TPkcsObjectIdentifiers.Boot;

+ 2 - 1
CryptoLib/src/Crypto/Digests/ClpDigestUtilities.pas

@@ -30,6 +30,7 @@ uses
   ClpNoOpDigest,
   ClpAsn1Objects,
   ClpCollectionUtilities,
+  ClpAsn1Comparers,
   ClpCryptoLibComparers,
   ClpCryptoLibTypes,
   ClpCryptoProObjectIdentifiers,
@@ -281,7 +282,7 @@ end;
 class procedure TDigestUtilities.Boot;
 begin
   FAlgorithmMap := TDictionary<String, String>.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
-  FAlgorithmOidMap := TDictionary<IDerObjectIdentifier, String>.Create(TCryptoLibComparers.OidEqualityComparer);
+  FAlgorithmOidMap := TDictionary<IDerObjectIdentifier, String>.Create(TAsn1Comparers.OidEqualityComparer);
   FOids := TDictionary<String, IDerObjectIdentifier>.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
 
   TPkcsObjectIdentifiers.Boot;

+ 3 - 2
CryptoLib/src/Crypto/EC/ClpCustomNamedCurves.pas

@@ -24,6 +24,7 @@ interface
 uses
   SysUtils,
   Generics.Collections,
+  ClpAsn1Comparers,
   ClpCryptoLibComparers,
   ClpEncoders,
   ClpGlvTypeBParameters,
@@ -343,8 +344,8 @@ begin
   FnameToCurve := TDictionary<String, IX9ECParametersHolder>.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
   FnameToOid := TDictionary<String, IDerObjectIdentifier>.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
   FoidToCurve := TDictionary<IDerObjectIdentifier,
-    IX9ECParametersHolder>.Create(TCryptoLibComparers.OidEqualityComparer);
-  FoidToName := TDictionary<IDerObjectIdentifier, String>.Create(TCryptoLibComparers.OidEqualityComparer);
+    IX9ECParametersHolder>.Create(TAsn1Comparers.OidEqualityComparer);
+  FoidToName := TDictionary<IDerObjectIdentifier, String>.Create(TAsn1Comparers.OidEqualityComparer);
 
   Fnames := TList<String>.Create();
 

+ 2 - 1
CryptoLib/src/Crypto/Macs/ClpMacUtilities.pas

@@ -26,6 +26,7 @@ uses
   Generics.Collections,
   ClpAsn1Objects,
   ClpCollectionUtilities,
+  ClpAsn1Comparers,
   ClpCryptoLibComparers,
   ClpCryptoLibTypes,
   ClpDigestUtilities,
@@ -79,7 +80,7 @@ implementation
 class procedure TMacUtilities.Boot;
 begin
   FAlgorithmMap := TDictionary<String, String>.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
-  FAlgorithmOidMap := TDictionary<IDerObjectIdentifier, String>.Create(TCryptoLibComparers.OidEqualityComparer);
+  FAlgorithmOidMap := TDictionary<IDerObjectIdentifier, String>.Create(TAsn1Comparers.OidEqualityComparer);
 
   TIanaObjectIdentifiers.Boot;
   TPkcsObjectIdentifiers.Boot;

+ 2 - 1
CryptoLib/src/Crypto/Signers/ClpSignerUtilities.pas

@@ -28,6 +28,7 @@ uses
   ClpAsn1Objects,
   ClpIX509Asn1Objects,
   ClpCollectionUtilities,
+  ClpAsn1Comparers,
   ClpCryptoLibComparers,
   ClpECNRSigner,
   ClpICipherParameters,
@@ -203,7 +204,7 @@ end;
 class procedure TSignerUtilities.Boot;
 begin
   FAlgorithmMap := TDictionary<String, String>.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
-  FAlgorithmOidMap := TDictionary<IDerObjectIdentifier, String>.Create(TCryptoLibComparers.OidEqualityComparer);
+  FAlgorithmOidMap := TDictionary<IDerObjectIdentifier, String>.Create(TAsn1Comparers.OidEqualityComparer);
   FNoRandom := TDictionary<String, Byte>.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
   FOids := TDictionary<String, IDerObjectIdentifier>.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
 

+ 0 - 115
CryptoLib/src/Misc/ClpCryptoLibComparers.pas

@@ -23,30 +23,9 @@ interface
 
 uses
   Generics.Defaults,
-  ClpIAsn1Objects,
   ClpStringUtilities;
 
 type
-  /// <summary>
-  /// Equality comparer for IDerObjectIdentifier that uses value-based comparison
-  /// (Asn1Equals) instead of reference equality. Used with TDictionary.
-  /// </summary>
-  TOidEqualityComparer = class(TInterfacedObject, IEqualityComparer<IDerObjectIdentifier>)
-  strict private
-    function Equals(const ALeft, ARight: IDerObjectIdentifier): Boolean; reintroduce;
-    function GetHashCode(const AValue: IDerObjectIdentifier): Integer;
-  end;
-
-  /// <summary>
-  /// Comparer for IDerObjectIdentifier that uses value-based comparison
-  /// (Asn1Equals) for equality and ID string comparison for ordering.
-  /// Used with TList to ensure Contains, IndexOf, and Remove work correctly.
-  /// </summary>
-  TOidComparer = class(TInterfacedObject, IComparer<IDerObjectIdentifier>)
-  strict private
-    function Compare(const ALeft, ARight: IDerObjectIdentifier): Integer;
-  end;
-
   /// <summary>
   /// Equality comparer for String that uses ordinal case-insensitive comparison.
   /// Uses invariant culture for case conversion (OrdinalIgnoreCase).
@@ -64,21 +43,9 @@ type
   TCryptoLibComparers = class sealed(TObject)
   strict private
     class var
-      FOidEqualityComparer: IEqualityComparer<IDerObjectIdentifier>;
-      FOidComparer: IComparer<IDerObjectIdentifier>;
       FOrdinalIgnoreCaseEqualityComparer: IEqualityComparer<String>;
     class constructor Create;
   public
-    /// <summary>
-    /// Gets the OID equality comparer for use with TDictionary.
-    /// </summary>
-    class property OidEqualityComparer: IEqualityComparer<IDerObjectIdentifier> read FOidEqualityComparer;
-    
-    /// <summary>
-    /// Gets the OID comparer for use with TList.
-    /// </summary>
-    class property OidComparer: IComparer<IDerObjectIdentifier> read FOidComparer;
-    
     /// <summary>
     /// Gets the string ordinal ignore case equality comparer for use with TDictionary.
     /// </summary>
@@ -87,86 +54,6 @@ type
 
 implementation
 
-{ TOidEqualityComparer }
-
-function TOidEqualityComparer.Equals(const ALeft, ARight: IDerObjectIdentifier): Boolean;
-begin
-  // Use value-based comparison via Asn1Equals
-  if ALeft = ARight then
-  begin
-    Result := True;
-    Exit;
-  end;
-  
-  if (ALeft = nil) or (ARight = nil) then
-  begin
-    Result := False;
-    Exit;
-  end;
-  
-  // Use Asn1Equals which compares the contents byte arrays
-  Result := ALeft.Equals(ARight);
-end;
-
-function TOidEqualityComparer.GetHashCode(const AValue: IDerObjectIdentifier): Integer;
-begin
-  if AValue = nil then
-  begin
-    Result := 0;
-    Exit;
-  end;
-  
-  // Use Asn1GetHashCode which is based on contents byte array
-  Result := AValue.CallAsn1GetHashCode();
-end;
-
-{ TOidComparer }
-
-function TOidComparer.Compare(const ALeft, ARight: IDerObjectIdentifier): Integer;
-begin
-  // If both are nil, they're equal
-  if (ALeft = nil) and (ARight = nil) then
-  begin
-    Result := 0;
-    Exit;
-  end;
-  
-  // nil is less than non-nil
-  if ALeft = nil then
-  begin
-    Result := -1;
-    Exit;
-  end;
-  
-  if ARight = nil then
-  begin
-    Result := 1;
-    Exit;
-  end;
-  
-  // If they're the same reference, they're equal
-  if ALeft = ARight then
-  begin
-    Result := 0;
-    Exit;
-  end;
-  
-  // Use value-based equality check (Asn1Equals)
-  if ALeft.Equals(ARight) then
-  begin
-    Result := 0;
-    Exit;
-  end;
-  
-  // If not equal, compare by ID string for ordering
-  if ALeft.Id < ARight.Id then
-    Result := -1
-  else if ALeft.Id > ARight.Id then
-    Result := 1
-  else
-    Result := 0; // Should not happen if Equals returned False, but handle it
-end;
-
 { TOrdinalIgnoreCaseEqualityComparer }
 
 function TOrdinalIgnoreCaseEqualityComparer.Equals(const ALeft, ARight: String): Boolean;
@@ -202,8 +89,6 @@ end;
 
 class constructor TCryptoLibComparers.Create;
 begin
-  FOidEqualityComparer := TOidEqualityComparer.Create();
-  FOidComparer := TOidComparer.Create();
   FOrdinalIgnoreCaseEqualityComparer := TOrdinalIgnoreCaseEqualityComparer.Create();
 end;
 

+ 3 - 2
CryptoLib/src/Pkcs/ClpPkcs10CertificationRequest.pas

@@ -55,6 +55,7 @@ uses
   ClpEdECObjectIdentifiers,
   ClpRosstandartObjectIdentifiers,
   ClpX9ObjectIdentifiers,
+  ClpAsn1Comparers,
   ClpCryptoLibComparers,
   ClpCryptoLibTypes;
 
@@ -144,8 +145,8 @@ var
 begin
   FAlgorithms := TDictionary<String, IDerObjectIdentifier>.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
   FExParams := TDictionary<String, IAsn1Encodable>.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
-  FNoParams := TDictionary<IDerObjectIdentifier, Boolean>.Create(TCryptoLibComparers.OidEqualityComparer);
-  FKeyAlgorithms := TDictionary<IDerObjectIdentifier, String>.Create(TCryptoLibComparers.OidEqualityComparer);
+  FNoParams := TDictionary<IDerObjectIdentifier, Boolean>.Create(TAsn1Comparers.OidEqualityComparer);
+  FKeyAlgorithms := TDictionary<IDerObjectIdentifier, String>.Create(TAsn1Comparers.OidEqualityComparer);
 
   // FAlgorithms
   FAlgorithms.Add('MD2WITHRSAENCRYPTION', TPkcsObjectIdentifiers.MD2WithRsaEncryption);