Browse Source

some more tests and refactorings.

Ugochukwu Mmaduekwe 7 years ago
parent
commit
87dbef04aa

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

@@ -508,7 +508,12 @@ uses
   ClpSecP256R1Point in '..\..\CryptoLib\src\Math\EC\Custom\Sec\ClpSecP256R1Point.pas',
   ClpSecP256R1Point in '..\..\CryptoLib\src\Math\EC\Custom\Sec\ClpSecP256R1Point.pas',
   ClpISecP256R1Curve in '..\..\CryptoLib\src\Interfaces\ClpISecP256R1Curve.pas',
   ClpISecP256R1Curve in '..\..\CryptoLib\src\Interfaces\ClpISecP256R1Curve.pas',
   ClpSecP256R1Curve in '..\..\CryptoLib\src\Math\EC\Custom\Sec\ClpSecP256R1Curve.pas',
   ClpSecP256R1Curve in '..\..\CryptoLib\src\Math\EC\Custom\Sec\ClpSecP256R1Curve.pas',
-  SecP256R1FieldTests in '..\src\Math\EC\Custom\Sec\SecP256R1FieldTests.pas';
+  SecP256R1FieldTests in '..\src\Math\EC\Custom\Sec\SecP256R1FieldTests.pas',
+  TagTests in '..\src\Asn1\TagTests.pas',
+  StringTests in '..\src\Asn1\StringTests.pas',
+  ParsingTests in '..\src\Asn1\ParsingTests.pas',
+  ParseTests in '..\src\Asn1\ParseTests.pas',
+  EnumeratedTests in '..\src\Asn1\EnumeratedTests.pas';
 
 
 begin
 begin
 
 

+ 21 - 1
CryptoLib.Tests/FreePascal.Tests/CryptoLib.Tests.lpi

@@ -36,7 +36,7 @@
         <PackageName Value="FCL"/>
         <PackageName Value="FCL"/>
       </Item4>
       </Item4>
     </RequiredPackages>
     </RequiredPackages>
-    <Units Count="42">
+    <Units Count="47">
       <Unit0>
       <Unit0>
         <Filename Value="CryptoLib.lpr"/>
         <Filename Value="CryptoLib.lpr"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
@@ -206,6 +206,26 @@
         <Filename Value="..\src\Math\EC\Custom\Sec\SecP256R1FieldTests.pas"/>
         <Filename Value="..\src\Math\EC\Custom\Sec\SecP256R1FieldTests.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
       </Unit41>
       </Unit41>
+      <Unit42>
+        <Filename Value="..\src\Asn1\EnumeratedTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit42>
+      <Unit43>
+        <Filename Value="..\src\Asn1\ParseTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit43>
+      <Unit44>
+        <Filename Value="..\src\Asn1\ParsingTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit44>
+      <Unit45>
+        <Filename Value="..\src\Asn1\StringTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit45>
+      <Unit46>
+        <Filename Value="..\src\Asn1\TagTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit46>
     </Units>
     </Units>
   </ProjectOptions>
   </ProjectOptions>
   <CompilerOptions>
   <CompilerOptions>

+ 5 - 0
CryptoLib.Tests/FreePascal.Tests/CryptoLib.lpr

@@ -10,6 +10,11 @@ uses
   DerApplicationSpecificTests,
   DerApplicationSpecificTests,
   EqualsAndHashCodeTests,
   EqualsAndHashCodeTests,
   OIDTests,
   OIDTests,
+  EnumeratedTests,
+  ParsingTests,
+  ParseTests,
+  StringTests,
+  TagTests,
   BigIntegerTests,
   BigIntegerTests,
   ECAlgorithmsTests,
   ECAlgorithmsTests,
   ECPointTests,
   ECPointTests,

+ 24 - 1
CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.Tests.lpi

@@ -17,6 +17,9 @@
       <Version Value="2"/>
       <Version Value="2"/>
     </PublishOptions>
     </PublishOptions>
     <RunParams>
     <RunParams>
+      <local>
+        <CommandLineParams Value="--format=plain --all --progress"/>
+      </local>
       <FormatVersion Value="2"/>
       <FormatVersion Value="2"/>
       <Modes Count="1">
       <Modes Count="1">
         <Mode0 Name="default">
         <Mode0 Name="default">
@@ -34,7 +37,7 @@
         <PackageName Value="FCL"/>
         <PackageName Value="FCL"/>
       </Item2>
       </Item2>
     </RequiredPackages>
     </RequiredPackages>
-    <Units Count="42">
+    <Units Count="47">
       <Unit0>
       <Unit0>
         <Filename Value="CryptoLibConsole.lpr"/>
         <Filename Value="CryptoLibConsole.lpr"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
@@ -203,6 +206,26 @@
         <Filename Value="..\src\Math\EC\Custom\Sec\SecP256R1FieldTests.pas"/>
         <Filename Value="..\src\Math\EC\Custom\Sec\SecP256R1FieldTests.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
       </Unit41>
       </Unit41>
+      <Unit42>
+        <Filename Value="..\src\Asn1\EnumeratedTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit42>
+      <Unit43>
+        <Filename Value="..\src\Asn1\ParseTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit43>
+      <Unit44>
+        <Filename Value="..\src\Asn1\ParsingTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit44>
+      <Unit45>
+        <Filename Value="..\src\Asn1\StringTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit45>
+      <Unit46>
+        <Filename Value="..\src\Asn1\TagTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit46>
     </Units>
     </Units>
   </ProjectOptions>
   </ProjectOptions>
   <CompilerOptions>
   <CompilerOptions>

+ 5 - 0
CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.lpr

@@ -8,6 +8,11 @@ uses
   DerApplicationSpecificTests,
   DerApplicationSpecificTests,
   EqualsAndHashCodeTests,
   EqualsAndHashCodeTests,
   OIDTests,
   OIDTests,
+  EnumeratedTests,
+  ParsingTests,
+  ParseTests,
+  StringTests,
+  TagTests,
   BigIntegerTests,
   BigIntegerTests,
   ECAlgorithmsTests,
   ECAlgorithmsTests,
   ECPointTests,
   ECPointTests,

+ 1 - 3
CryptoLib.Tests/src/Asn1/DerApplicationSpecificTests.pas

@@ -60,12 +60,11 @@ type
   var
   var
     FimpData, FcertData, FsampleData: TCryptoLibByteArray;
     FimpData, FcertData, FsampleData: TCryptoLibByteArray;
 
 
-    procedure TestTaggedObject();
-
   protected
   protected
     procedure SetUp; override;
     procedure SetUp; override;
     procedure TearDown; override;
     procedure TearDown; override;
   published
   published
+    procedure TestTaggedObject();
     procedure TestDerApplicationSpecific;
     procedure TestDerApplicationSpecific;
 
 
   end;
   end;
@@ -110,7 +109,6 @@ var
   appSpec, tagged, certObj: IDerApplicationSpecific;
   appSpec, tagged, certObj: IDerApplicationSpecific;
   recVal, val: IDerInteger;
   recVal, val: IDerInteger;
 begin
 begin
-  TestTaggedObject();
 
 
   appSpec := TAsn1Object.FromByteArray(FsampleData) as IDerApplicationSpecific;
   appSpec := TAsn1Object.FromByteArray(FsampleData) as IDerApplicationSpecific;
 
 

+ 202 - 0
CryptoLib.Tests/src/Asn1/EnumeratedTests.pas

@@ -0,0 +1,202 @@
+{ *********************************************************************************** }
+{ *                              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 EnumeratedTests;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+  SysUtils,
+{$IFDEF FPC}
+  fpcunit,
+  testregistry,
+{$ELSE}
+  TestFramework,
+{$ENDIF FPC}
+  ClpIProxiedInterface,
+  ClpAsn1Object,
+  ClpIDerSequence,
+  ClpIDerEnumerated,
+  ClpIDerBoolean,
+  ClpIDerObjectIdentifier,
+  ClpHex;
+
+type
+
+  TCryptoLibTestCase = class abstract(TTestCase)
+
+  end;
+
+type
+
+  /// <summary>
+  /// Tests used to verify correct decoding of the ENUMERATED type.
+  /// </summary>
+  TTestEnumerated = class(TCryptoLibTestCase)
+  var
+  private
+    FMultipleSingleByteItems, FMultipleDoubleByteItems,
+      FMultipleTripleByteItems: TBytes;
+
+  protected
+    procedure SetUp; override;
+    procedure TearDown; override;
+  published
+    /// <summary>
+    /// Makes sure multiple identically sized values are parsed correctly.
+    /// </summary>
+    procedure TestReadingMultipleSingleByteItems;
+    /// <summary>
+    /// Makes sure multiple identically sized values are parsed correctly.
+    /// </summary>
+    procedure TestReadingMultipleDoubleByteItems;
+    /// <summary>
+    /// Makes sure multiple identically sized values are parsed correctly.
+    /// </summary>
+    procedure TestReadingMultipleTripleByteItems;
+
+  end;
+
+implementation
+
+{ TTestEnumerated }
+
+procedure TTestEnumerated.SetUp;
+begin
+  inherited;
+  /// <summary>
+  /// Test vector used to test decoding of multiple items.
+  /// </summary>
+  /// <remarks>This sample uses an ENUMERATED and a BOOLEAN.</remarks>
+  FMultipleSingleByteItems := THex.Decode('30060a01010101ff');
+  /// <summary>
+  /// Test vector used to test decoding of multiple items.
+  /// </summary>
+  /// <remarks>This sample uses two ENUMERATEDs.</remarks>
+  FMultipleDoubleByteItems := THex.Decode('30080a0201010a020202');
+  /// <summary>
+  /// Test vector used to test decoding of multiple items.
+  /// </summary>
+  /// <remarks>This sample uses an ENUMERATED and an OBJECT IDENTIFIER.</remarks>
+  FMultipleTripleByteItems := THex.Decode('300a0a0301010106032b0601');
+end;
+
+procedure TTestEnumerated.TearDown;
+begin
+  inherited;
+
+end;
+
+procedure TTestEnumerated.TestReadingMultipleSingleByteItems;
+var
+  obj: IAsn1Object;
+  sequence: IDerSequence;
+  enumerated: IDerEnumerated;
+  boolean: IDerBoolean;
+begin
+  obj := TAsn1Object.FromByteArray(FMultipleSingleByteItems);
+
+  CheckTrue(Supports(obj, IDerSequence), 'Null ASN.1 SEQUENCE');
+
+  sequence := obj as IDerSequence;
+
+  CheckEquals(2, sequence.Count, '2 items expected');
+
+  enumerated := sequence[0] as IDerEnumerated;
+
+  CheckNotNull(enumerated, 'ENUMERATED expected');
+
+  CheckEquals(1, enumerated.Value.Int32Value, 'Unexpected ENUMERATED value');
+
+  boolean := sequence[1] as IDerBoolean;
+
+  CheckNotNull(boolean, 'BOOLEAN expected');
+
+  CheckTrue(boolean.IsTrue, 'Unexpected BOOLEAN value');
+end;
+
+procedure TTestEnumerated.TestReadingMultipleDoubleByteItems;
+var
+  obj: IAsn1Object;
+  sequence: IDerSequence;
+  enumerated, enumerated2: IDerEnumerated;
+begin
+  obj := TAsn1Object.FromByteArray(FMultipleDoubleByteItems);
+
+  CheckTrue(Supports(obj, IDerSequence), 'Null ASN.1 SEQUENCE');
+
+  sequence := obj as IDerSequence;
+
+  CheckEquals(2, sequence.Count, '2 items expected');
+
+  enumerated := sequence[0] as IDerEnumerated;
+
+  CheckNotNull(enumerated, 'ENUMERATED expected');
+
+  CheckEquals(257, enumerated.Value.Int32Value, 'Unexpected ENUMERATED value');
+
+  enumerated2 := sequence[1] as IDerEnumerated;
+
+  CheckNotNull(enumerated2, 'ENUMERATED expected');
+
+  CheckEquals(514, enumerated2.Value.Int32Value, 'Unexpected ENUMERATED value');
+end;
+
+procedure TTestEnumerated.TestReadingMultipleTripleByteItems;
+var
+  obj: IAsn1Object;
+  sequence: IDerSequence;
+  enumerated: IDerEnumerated;
+  objectId: IDerObjectIdentifier;
+begin
+  obj := TAsn1Object.FromByteArray(FMultipleTripleByteItems);
+
+  CheckTrue(Supports(obj, IDerSequence), 'Null ASN.1 SEQUENCE');
+
+  sequence := obj as IDerSequence;
+
+  CheckEquals(2, sequence.Count, '2 items expected');
+
+  enumerated := sequence[0] as IDerEnumerated;
+
+  CheckNotNull(enumerated, 'ENUMERATED expected');
+
+  CheckEquals(65793, enumerated.Value.Int32Value,
+    'Unexpected ENUMERATED value');
+
+  objectId := sequence[1] as IDerObjectIdentifier;
+
+  CheckNotNull(objectId, 'OBJECT IDENTIFIER expected');
+
+  CheckEquals('1.3.6.1', objectId.Id, 'Unexpected OBJECT IDENTIFIER value');
+end;
+
+initialization
+
+// Register any test cases with the test runner
+
+{$IFDEF FPC}
+  RegisterTest(TTestEnumerated);
+{$ELSE}
+  RegisterTest(TTestEnumerated.Suite);
+{$ENDIF FPC}
+
+end.

+ 2 - 1
CryptoLib.Tests/src/Asn1/EqualsAndHashCodeTests.pas

@@ -119,7 +119,8 @@ begin
     TDerUtf8String.Create('hello world'),
     TDerUtf8String.Create('hello world'),
     TDerVisibleString.Create('hello world'),
     TDerVisibleString.Create('hello world'),
     TDerGraphicString.Create(THex.Decode('deadbeef')),
     TDerGraphicString.Create(THex.Decode('deadbeef')),
-    TDerVideotexString.Create(TConverters.ConvertStringToBytes('Hello World', TEncoding.ASCII)),
+    TDerVideotexString.Create(TConverters.ConvertStringToBytes('Hello World',
+    TEncoding.ANSI)),
 
 
     TBerTaggedObject.Create(0, TDerPrintableString.Create('hello world')
     TBerTaggedObject.Create(0, TDerPrintableString.Create('hello world')
     as IDerPrintableString),
     as IDerPrintableString),

+ 96 - 0
CryptoLib.Tests/src/Asn1/ParseTests.pas

@@ -0,0 +1,96 @@
+{ *********************************************************************************** }
+{ *                              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 ParseTests;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+  SysUtils,
+{$IFDEF FPC}
+  fpcunit,
+  testregistry,
+{$ELSE}
+  TestFramework,
+{$ENDIF FPC}
+  ClpAsn1StreamParser,
+  ClpIAsn1StreamParser,
+  ClpIAsn1TaggedObjectParser,
+  ClpHex;
+
+type
+
+  TCryptoLibTestCase = class abstract(TTestCase)
+
+  end;
+
+type
+  TTestParse = class(TCryptoLibTestCase)
+  var
+  private
+    FlongTagged: TBytes;
+
+  protected
+    procedure SetUp; override;
+    procedure TearDown; override;
+  published
+    procedure TestParse;
+
+  end;
+
+implementation
+
+{ TTestParse }
+
+procedure TTestParse.SetUp;
+begin
+  inherited;
+  FlongTagged := THex.Decode('9f1f023330');
+end;
+
+procedure TTestParse.TearDown;
+begin
+  inherited;
+
+end;
+
+procedure TTestParse.TestParse;
+var
+  aIn: IAsn1StreamParser;
+  tagged: IAsn1TaggedObjectParser;
+begin
+  aIn := TAsn1StreamParser.Create(FlongTagged);
+  tagged := aIn.ReadObject() as IAsn1TaggedObjectParser;
+
+  CheckEquals(31, tagged.TagNo);
+end;
+
+initialization
+
+// Register any test cases with the test runner
+
+{$IFDEF FPC}
+  RegisterTest(TTestParse);
+{$ELSE}
+  RegisterTest(TTestParse.Suite);
+{$ENDIF FPC}
+
+end.

+ 189 - 0
CryptoLib.Tests/src/Asn1/ParsingTests.pas

@@ -0,0 +1,189 @@
+{ *********************************************************************************** }
+{ *                              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 ParsingTests;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+  SysUtils,
+{$IFDEF FPC}
+  fpcunit,
+  testregistry,
+{$ELSE}
+  TestFramework,
+{$ENDIF FPC}
+  ClpAsn1StreamParser,
+  ClpIAsn1StreamParser,
+  ClpAsn1InputStream,
+  ClpBase64,
+  ClpCryptoLibTypes;
+
+type
+
+  TCryptoLibTestCase = class abstract(TTestCase)
+
+  end;
+
+type
+  TTestParsing = class(TCryptoLibTestCase)
+  var
+  private
+    FStreams: TCryptoLibStringArray;
+
+  protected
+    procedure SetUp; override;
+    procedure TearDown; override;
+  published
+    procedure TestParsing;
+    procedure TestInputStream;
+
+  end;
+
+implementation
+
+{ TTestParsing }
+
+procedure TTestParsing.SetUp;
+begin
+  inherited;
+      FStreams := TCryptoLibStringArray.Create(
+			'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',
+//		 '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'
+);
+
+end;
+
+procedure TTestParsing.TearDown;
+begin
+  inherited;
+
+end;
+
+procedure TTestParsing.TestInputStream;
+var
+  stream: String;
+  aIn: TAsn1InputStream;
+  obj: IInterface;
+begin
+  for stream in FStreams do
+  begin
+    aIn := TAsn1InputStream.Create(TBase64.Decode(stream));
+
+    try
+
+      try
+
+        obj := aIn.ReadObject();
+        while obj <> Nil do
+        begin
+
+          obj := aIn.ReadObject();
+        end;
+        Fail('bad stream parsed successfully!');
+
+      except
+        on e: EIOCryptoLibException do
+        begin
+          // ignore
+        end;
+
+        on e: EAsn1ParsingCryptoLibException do
+        begin
+          // ignore
+        end;
+
+        on e: EAsn1CryptoLibException do
+        begin
+          // ignore
+        end;
+
+      end;
+    finally
+      aIn.Free;
+    end;
+  end;
+
+end;
+
+procedure TTestParsing.TestParsing;
+var
+  stream: String;
+  aIn: IAsn1StreamParser;
+  obj: IInterface;
+begin
+  for stream in FStreams do
+  begin
+    aIn := TAsn1StreamParser.Create(TBase64.Decode(stream));
+
+    try
+
+      obj := aIn.ReadObject();
+      while obj <> Nil do
+      begin
+
+        obj := aIn.ReadObject();
+      end;
+      Fail('bad stream parsed successfully!');
+
+    except
+      on e: EIOCryptoLibException do
+      begin
+        // ignore
+      end;
+
+      on e: EAsn1CryptoLibException do
+      begin
+        // ignore
+      end;
+
+    end;
+  end;
+
+end;
+
+initialization
+
+// Register any test cases with the test runner
+
+{$IFDEF FPC}
+  RegisterTest(TTestParsing);
+{$ELSE}
+  RegisterTest(TTestParsing.Suite);
+{$ENDIF FPC}
+
+end.

+ 171 - 0
CryptoLib.Tests/src/Asn1/StringTests.pas

@@ -0,0 +1,171 @@
+{ *********************************************************************************** }
+{ *                              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 StringTests;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+  SysUtils,
+{$IFDEF FPC}
+  fpcunit,
+  testregistry,
+{$ELSE}
+  TestFramework,
+{$ENDIF FPC}
+  ClpDerBitString,
+  ClpIDerBitString,
+  ClpDerUniversalString,
+  ClpIDerUniversalString,
+  ClpDerT61String,
+  ClpIDerT61String,
+  ClpConverters;
+
+type
+
+  TCryptoLibTestCase = class abstract(TTestCase)
+
+  end;
+
+type
+
+  /// <summary>
+  /// X.690 test example
+  /// </summary>
+  TTestString = class(TCryptoLibTestCase)
+
+  protected
+    procedure SetUp; override;
+    procedure TearDown; override;
+  published
+    procedure TestString;
+
+  end;
+
+implementation
+
+{ TTestString }
+
+procedure TTestString.SetUp;
+begin
+  inherited;
+
+end;
+
+procedure TTestString.TearDown;
+begin
+  inherited;
+
+end;
+
+procedure TTestString.TestString;
+var
+  bs: IDerBitString;
+  us: IDerUniversalString;
+  t61: IDerT61String;
+  t61Bytes: TBytes;
+  t61String: string;
+  LEncoding: TEncoding;
+begin
+  bs := TDerBitString.Create(TBytes.Create($01, $23, $45, $67, $89, $AB,
+    $CD, $EF));
+
+  if (not(bs.GetString() = ('#0309000123456789ABCDEF'))) then
+  begin
+    Fail('DerBitString.GetString() result incorrect');
+  end;
+
+  if (not(bs.ToString() = ('#0309000123456789ABCDEF'))) then
+  begin
+    Fail('DerBitString.ToString() result incorrect');
+  end;
+
+  bs := TDerBitString.Create(TBytes.Create($FE, $DC, $BA, $98, $76, $54,
+    $32, $10));
+
+  if (not(bs.GetString() = ('#030900FEDCBA9876543210'))) then
+  begin
+    Fail('DerBitString.GetString() result incorrect');
+  end;
+
+  if (not(bs.ToString() = ('#030900FEDCBA9876543210'))) then
+  begin
+    Fail('DerBitString.ToString() result incorrect');
+  end;
+
+  us := TDerUniversalString.Create(TBytes.Create($01, $23, $45, $67, $89, $AB,
+    $CD, $EF));
+
+  if (not(us.GetString() = ('#1C080123456789ABCDEF'))) then
+  begin
+    Fail('DerUniversalString.GetString() result incorrect');
+  end;
+
+  if (not(us.ToString() = ('#1C080123456789ABCDEF'))) then
+  begin
+    Fail('DerUniversalString.ToString() result incorrect');
+  end;
+
+  us := TDerUniversalString.Create(TBytes.Create($FE, $DC, $BA, $98, $76, $54,
+    $32, $10));
+
+  if (not(us.GetString() = ('#1C08FEDCBA9876543210'))) then
+  begin
+    Fail('DerUniversalString.GetString() result incorrect');
+  end;
+
+  if (not(us.ToString() = ('#1C08FEDCBA9876543210'))) then
+  begin
+    Fail('DerUniversalString.ToString() result incorrect');
+  end;
+
+  t61Bytes := TBytes.Create($FF, $FE, $FD, $FC, $FB, $FA, $F9, $F8);
+  LEncoding := TEncoding.GetEncoding('iso-8859-1');
+  try
+    t61String := TConverters.ConvertBytesToString(t61Bytes, LEncoding);
+  finally
+    LEncoding.Free;
+  end;
+
+  t61 := TDerT61String.Create(t61Bytes);
+
+  if (not(t61.GetString() = (t61String))) then
+  begin
+    Fail('DerT61String.GetString() result incorrect');
+  end;
+
+  if (not(t61.ToString() = (t61String))) then
+  begin
+    Fail('DerT61String.ToString() result incorrect');
+  end;
+end;
+
+initialization
+
+// Register any test cases with the test runner
+
+{$IFDEF FPC}
+  RegisterTest(TTestString);
+{$ELSE}
+  RegisterTest(TTestString.Suite);
+{$ENDIF FPC}
+
+end.

+ 201 - 0
CryptoLib.Tests/src/Asn1/TagTests.pas

@@ -0,0 +1,201 @@
+{ *********************************************************************************** }
+{ *                              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 TagTests;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+  SysUtils,
+{$IFDEF FPC}
+  fpcunit,
+  testregistry,
+{$ELSE}
+  TestFramework,
+{$ENDIF FPC}
+  ClpAsn1Object,
+  ClpAsn1InputStream,
+  ClpDerApplicationSpecific,
+  ClpIDerApplicationSpecific,
+  ClpIAsn1TaggedObject,
+  ClpSecureRandom,
+  ClpISecureRandom,
+  ClpBits,
+  ClpHex,
+  ClpBase64,
+  ClpCryptoLibTypes;
+
+type
+
+  TCryptoLibTestCase = class abstract(TTestCase)
+
+  end;
+
+type
+
+  /// <summary>
+  /// X.690 test example
+  /// </summary>
+  TTestTag = class(TCryptoLibTestCase)
+  private
+
+  var
+    FlongAppSpecificTag, FlongTagged: TCryptoLibByteArray;
+
+  protected
+    procedure SetUp; override;
+    procedure TearDown; override;
+  published
+    procedure TestTag;
+
+  end;
+
+implementation
+
+{ TTestTag }
+
+procedure TTestTag.SetUp;
+begin
+  inherited;
+  FlongAppSpecificTag := THex.Decode('5F610101');
+
+  FlongTagged := TBase64.Decode
+    ('ZSRzIp8gEEZFRENCQTk4NzY1NDMyMTCfIQwyMDA2MDQwMTEyMzSUCCAFERVz' +
+    'A4kCAHEXGBkalAggBRcYGRqUCCAFZS6QAkRFkQlURUNITklLRVKSBQECAwQF' +
+    'kxAREhMUFRYXGBkalAggBREVcwOJAgBxFxgZGpQIIAUXGBkalAggBWUukAJE' +
+    'RZEJVEVDSE5JS0VSkgUBAgMEBZMQERITFBUWFxgZGpQIIAURFXMDiQIAcRcY' +
+    'GRqUCCAFFxgZGpQIIAVlLpACREWRCVRFQ0hOSUtFUpIFAQIDBAWTEBESExQV' +
+    'FhcYGRqUCCAFERVzA4kCAHEXGBkalAggBRcYGRqUCCAFFxgZGpQIIAUXGBka' + 'lAg=');
+
+end;
+
+procedure TTestTag.TearDown;
+begin
+  inherited;
+
+end;
+
+procedure TTestTag.TestTag;
+var
+  aIn: TAsn1InputStream;
+  app: IDerApplicationSpecific;
+  tagged: IAsn1TaggedObject;
+  sr: ISecureRandom;
+  TestTag, I: Int32;
+begin
+
+  aIn := TAsn1InputStream.Create(FlongTagged);
+  try
+    app := aIn.ReadObject() as IDerApplicationSpecific;
+  finally
+    aIn.Free;
+  end;
+
+  aIn := TAsn1InputStream.Create(app.GetContents());
+  try
+    app := aIn.ReadObject() as IDerApplicationSpecific;
+  finally
+    aIn.Free;
+  end;
+
+  aIn := TAsn1InputStream.Create(app.GetContents());
+  try
+    tagged := aIn.ReadObject() as IAsn1TaggedObject;
+
+    if (tagged.TagNo <> 32) then
+    begin
+      Fail('unexpected tag value found - not 32');
+    end;
+
+    tagged := TAsn1Object.FromByteArray(tagged.GetEncoded())
+      as IAsn1TaggedObject;
+
+    if (tagged.TagNo <> 32) then
+    begin
+      Fail('unexpected tag value found on recode - not 32');
+    end;
+
+    tagged := aIn.ReadObject() as IAsn1TaggedObject;
+
+  finally
+    aIn.Free;
+  end;
+
+  if (tagged.TagNo <> 33) then
+  begin
+    Fail('unexpected tag value found - not 33');
+  end;
+
+  tagged := TAsn1Object.FromByteArray(tagged.GetEncoded()) as IAsn1TaggedObject;
+
+  if (tagged.TagNo <> 33) then
+  begin
+    Fail('unexpected tag value found on recode - not 33');
+  end;
+
+  aIn := TAsn1InputStream.Create(FlongAppSpecificTag);
+  try
+    app := aIn.ReadObject() as IDerApplicationSpecific;
+  finally
+    aIn.Free;
+  end;
+
+  if (app.ApplicationTag <> 97) then
+  begin
+    Fail('incorrect tag number read');
+  end;
+
+  app := TAsn1Object.FromByteArray(app.GetEncoded()) as IDerApplicationSpecific;
+
+  if (app.ApplicationTag <> 97) then
+  begin
+    Fail('incorrect tag number read on recode');
+  end;
+
+  sr := TSecureRandom.Create();
+
+  for I := 0 to System.Pred(100) do
+  begin
+    TestTag := TBits.Asr32(sr.NextInt32() and System.High(Int32), sr.Next(26));
+    app := TDerApplicationSpecific.Create(TestTag, TBytes.Create(1));
+    app := TAsn1Object.FromByteArray(app.GetEncoded())
+      as IDerApplicationSpecific;
+
+    if (app.ApplicationTag <> TestTag) then
+    begin
+      Fail(Format
+        ('incorrect tag number read on recode (random test value: " %d ")',
+        [TestTag]));
+    end;
+  end;
+end;
+
+initialization
+
+// Register any test cases with the test runner
+
+{$IFDEF FPC}
+  RegisterTest(TTestTag);
+{$ELSE}
+  RegisterTest(TTestTag.Suite);
+{$ENDIF FPC}
+
+end.

+ 2 - 1
CryptoLib/src/Asn1/ClpAsn1InputStream.pas

@@ -353,7 +353,7 @@ end;
 destructor TAsn1InputStream.Destroy;
 destructor TAsn1InputStream.Destroy;
 begin
 begin
   FStream.Free;
   FStream.Free;
-  inherited Destroy; // dont free
+  inherited Destroy;
 end;
 end;
 
 
 constructor TAsn1InputStream.Create(const inputStream: TStream; limit: Int32);
 constructor TAsn1InputStream.Create(const inputStream: TStream; limit: Int32);
@@ -659,6 +659,7 @@ begin
         end;
         end;
     else
     else
       begin
       begin
+        defIn.Free; // free the stream incase an unsupported tag is encountered.
         raise EIOCryptoLibException.CreateResFmt(@SUnknownTag, [tagNo]);
         raise EIOCryptoLibException.CreateResFmt(@SUnknownTag, [tagNo]);
       end;
       end;
 
 

+ 8 - 2
CryptoLib/src/Asn1/ClpAsn1Object.pas

@@ -114,7 +114,10 @@ begin
       input.Free;
       input.Free;
     end;
     end;
   except
   except
-    raise EIOCryptoLibException.CreateRes(@SUnRecognizedObjectByteArray);
+    on e: EInvalidCastCryptoLibException do
+    begin
+      raise EIOCryptoLibException.CreateRes(@SUnRecognizedObjectByteArray);
+    end;
   end;
   end;
 end;
 end;
 
 
@@ -127,7 +130,10 @@ begin
     try
     try
       result := asn1Stream.ReadObject();
       result := asn1Stream.ReadObject();
     except
     except
-      raise EIOCryptoLibException.CreateRes(@SUnRecognizedObjectStream);
+      on e: EInvalidCastCryptoLibException do
+      begin
+        raise EIOCryptoLibException.CreateRes(@SUnRecognizedObjectStream);
+      end;
     end;
     end;
   finally
   finally
     asn1Stream.Free;
     asn1Stream.Free;

+ 1 - 0
CryptoLib/src/Asn1/ClpAsn1StreamParser.pas

@@ -375,6 +375,7 @@ begin
         end;
         end;
     else
     else
       begin
       begin
+        defIn.Free; // free the stream incase an unsupported tag is encountered.
         raise EIOCryptoLibException.CreateResFmt(@SUnknownTag, [tagNo]);
         raise EIOCryptoLibException.CreateResFmt(@SUnknownTag, [tagNo]);
       end;
       end;
 
 

+ 8 - 0
CryptoLib/src/Asn1/ClpBerTaggedObjectParser.pas

@@ -49,6 +49,8 @@ type
     constructor Create(constructed: Boolean; tagNumber: Int32;
     constructor Create(constructed: Boolean; tagNumber: Int32;
       const parser: IAsn1StreamParser);
       const parser: IAsn1StreamParser);
 
 
+    destructor Destroy; override;
+
     function GetObjectParser(tag: Int32; isExplicit: Boolean)
     function GetObjectParser(tag: Int32; isExplicit: Boolean)
       : IAsn1Convertible; inline;
       : IAsn1Convertible; inline;
 
 
@@ -71,6 +73,12 @@ begin
   F_parser := parser;
   F_parser := parser;
 end;
 end;
 
 
+destructor TBerTaggedObjectParser.Destroy;
+begin
+  F_parser := Nil;
+  inherited Destroy;
+end;
+
 function TBerTaggedObjectParser.GetIsConstructed: Boolean;
 function TBerTaggedObjectParser.GetIsConstructed: Boolean;
 begin
 begin
   result := F_constructed;
   result := F_constructed;

+ 1 - 1
CryptoLib/src/Asn1/ClpDerGraphicString.pas

@@ -194,7 +194,7 @@ end;
 
 
 function TDerGraphicString.GetString: String;
 function TDerGraphicString.GetString: String;
 begin
 begin
-  result := TConverters.ConvertBytesToString(mString, TEncoding.ASCII);
+  result := TConverters.ConvertBytesToString(mString, TEncoding.ANSI);
 end;
 end;
 
 
 end.
 end.

+ 2 - 2
CryptoLib/src/Asn1/ClpDerT61String.pas

@@ -114,7 +114,7 @@ end;
 
 
 function TDerT61String.GetOctets: TCryptoLibByteArray;
 function TDerT61String.GetOctets: TCryptoLibByteArray;
 begin
 begin
-  result := TConverters.ConvertStringToBytes(Str, TEncoding.ASCII);
+  result := TConverters.ConvertStringToBytes(Str, TEncoding.ANSI);
 end;
 end;
 
 
 function TDerT61String.Asn1Equals(const asn1Object: IAsn1Object): Boolean;
 function TDerT61String.Asn1Equals(const asn1Object: IAsn1Object): Boolean;
@@ -133,7 +133,7 @@ end;
 
 
 constructor TDerT61String.Create(const Str: TCryptoLibByteArray);
 constructor TDerT61String.Create(const Str: TCryptoLibByteArray);
 begin
 begin
-  Create(TConverters.ConvertBytesToString(Str, TEncoding.ASCII));
+  Create(TConverters.ConvertBytesToString(Str, TEncoding.ANSI));
 end;
 end;
 
 
 constructor TDerT61String.Create(const Str: String);
 constructor TDerT61String.Create(const Str: String);

+ 1 - 1
CryptoLib/src/Asn1/ClpDerVideotexString.pas

@@ -194,7 +194,7 @@ end;
 
 
 function TDerVideotexString.GetString: String;
 function TDerVideotexString.GetString: String;
 begin
 begin
-  result := TConverters.ConvertBytesToString(mString, TEncoding.ASCII)
+  result := TConverters.ConvertBytesToString(mString, TEncoding.ANSI)
 end;
 end;
 
 
 end.
 end.

+ 1 - 1
CryptoLib/src/Crypto/Engines/ClpIESEngine.pas

@@ -584,7 +584,7 @@ begin
   // Create input to KDF.
   // Create input to KDF.
   if (System.Length(FV) <> 0) then
   if (System.Length(FV) <> 0) then
   begin
   begin
-    VZ := TArrayUtils.AddByteArray(FV, BigZ);
+    VZ := TArrayUtils.Concatenate(FV, BigZ);
     System.FillChar(BigZ[0], System.Length(BigZ) * System.SizeOf(Byte),
     System.FillChar(BigZ[0], System.Length(BigZ) * System.SizeOf(Byte),
       Byte(0));
       Byte(0));
     BigZ := VZ;
     BigZ := VZ;

+ 7 - 7
CryptoLib/src/Utils/ClpArrayUtils.pas

@@ -37,13 +37,13 @@ type
 
 
   public
   public
 
 
-    class function AddStringArray(const A, B: TCryptoLibStringArray)
-      : TCryptoLibStringArray; static;
+    class function Concatenate(const A, B: TCryptoLibStringArray)
+      : TCryptoLibStringArray; overload; static;
 
 
-    class function AddByteArray(const A, B: TCryptoLibByteArray)
+    class function Concatenate(const A, B: TCryptoLibByteArray)
       : TCryptoLibByteArray; overload; static; inline;
       : TCryptoLibByteArray; overload; static; inline;
 
 
-    class function AddByteArray(const A: TCryptoLibByteArray;
+    class function Concatenate(const A: TCryptoLibByteArray;
       const Others: TCryptoLibMatrixByteArray): TCryptoLibByteArray;
       const Others: TCryptoLibMatrixByteArray): TCryptoLibByteArray;
       overload; static;
       overload; static;
 
 
@@ -99,7 +99,7 @@ begin
   Result := newLength;
   Result := newLength;
 end;
 end;
 
 
-class function TArrayUtils.AddByteArray(const A, B: TCryptoLibByteArray)
+class function TArrayUtils.Concatenate(const A, B: TCryptoLibByteArray)
   : TCryptoLibByteArray;
   : TCryptoLibByteArray;
 var
 var
   l: Int32;
   l: Int32;
@@ -110,7 +110,7 @@ begin
   System.Move(B[0], Result[l], System.Length(B) * System.SizeOf(Byte));
   System.Move(B[0], Result[l], System.Length(B) * System.SizeOf(Byte));
 end;
 end;
 
 
-class function TArrayUtils.AddByteArray(const A: TCryptoLibByteArray;
+class function TArrayUtils.Concatenate(const A: TCryptoLibByteArray;
   const Others: TCryptoLibMatrixByteArray): TCryptoLibByteArray;
   const Others: TCryptoLibMatrixByteArray): TCryptoLibByteArray;
 var
 var
   len, Idx, Pos: Int32;
   len, Idx, Pos: Int32;
@@ -134,7 +134,7 @@ begin
   end;
   end;
 end;
 end;
 
 
-class function TArrayUtils.AddStringArray(const A, B: TCryptoLibStringArray)
+class function TArrayUtils.Concatenate(const A, B: TCryptoLibStringArray)
   : TCryptoLibStringArray;
   : TCryptoLibStringArray;
 var
 var
   i, l: Int32;
   i, l: Int32;

+ 2 - 1
CryptoLib/src/Utils/ClpCryptoLibTypes.pas

@@ -32,6 +32,7 @@ type
   PUInt64 = ^UInt64;
   PUInt64 = ^UInt64;
 {$ENDIF FPC}
 {$ENDIF FPC}
   ECryptoLibException = class(Exception);
   ECryptoLibException = class(Exception);
+  EInvalidCastCryptoLibException = class(EInvalidCast);
   EArithmeticCryptoLibException = class(ECryptoLibException);
   EArithmeticCryptoLibException = class(ECryptoLibException);
   EInvalidOperationCryptoLibException = class(ECryptoLibException);
   EInvalidOperationCryptoLibException = class(ECryptoLibException);
   EInvalidParameterCryptoLibException = class(ECryptoLibException);
   EInvalidParameterCryptoLibException = class(ECryptoLibException);
@@ -45,7 +46,7 @@ type
   EFormatCryptoLibException = class(ECryptoLibException);
   EFormatCryptoLibException = class(ECryptoLibException);
   ENotImplementedCryptoLibException = class(ECryptoLibException);
   ENotImplementedCryptoLibException = class(ECryptoLibException);
   ENotSupportedCryptoLibException = class(ECryptoLibException);
   ENotSupportedCryptoLibException = class(ECryptoLibException);
-  EEndOfStreamCryptoLibException = class(ECryptoLibException);
+  EEndOfStreamCryptoLibException = class(EIOCryptoLibException);
   EStreamOverflowCryptoLibException = class(ECryptoLibException);
   EStreamOverflowCryptoLibException = class(ECryptoLibException);
   EAsn1CryptoLibException = class(ECryptoLibException);
   EAsn1CryptoLibException = class(ECryptoLibException);
   EAsn1ParsingCryptoLibException = class(ECryptoLibException);
   EAsn1ParsingCryptoLibException = class(ECryptoLibException);