diff --git a/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.Mobile.dpr b/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.Mobile.dpr
index dc9d03c7..575fd462 100644
--- a/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.Mobile.dpr
+++ b/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.Mobile.dpr
@@ -819,6 +819,7 @@ uses
Asn1IntegerTests in '..\src\Asn1\Asn1IntegerTests.pas',
Asn1GeneratorTests in '..\src\Asn1\Asn1GeneratorTests.pas',
Asn1SequenceParserTests in '..\src\Asn1\Asn1SequenceParserTests.pas',
+ Asn1SequenceCursorTests in '..\src\Asn1\Asn1SequenceCursorTests.pas',
Asn1TimeFormatTests in '..\src\Asn1\Asn1TimeFormatTests.pas',
BitStringTests in '..\src\Asn1\BitStringTests.pas',
DerUtf8StringTests in '..\src\Asn1\DerUtf8StringTests.pas',
@@ -864,6 +865,7 @@ uses
CtrDrbgTests in '..\src\Rngs\Drbg\CtrDrbgTests.pas',
//FixedPointTests in '..\src\Math\EC\FixedPointTests.pas',
AESTests in '..\src\Crypto\AESTests.pas',
+ BlockCipherTestBase in '..\src\Crypto\BlockCipherTestBase.pas',
AesBlockCipherTestBase in '..\src\Crypto\AesBlockCipherTestBase.pas',
AesLightTests in '..\src\Crypto\AesLightTests.pas',
FusedExternalRegistrationTests in '..\src\Crypto\FusedExternalRegistrationTests.pas',
diff --git a/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.Mobile.dproj b/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.Mobile.dproj
index 0993ce34..f0c8319e 100644
--- a/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.Mobile.dproj
+++ b/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.Mobile.dproj
@@ -1162,6 +1162,7 @@
+
@@ -1203,6 +1204,7 @@
+
diff --git a/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr b/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr
index 9080b797..261747d0 100644
--- a/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr
+++ b/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr
@@ -838,6 +838,7 @@ uses
Asn1IntegerTests in '..\src\Asn1\Asn1IntegerTests.pas',
Asn1GeneratorTests in '..\src\Asn1\Asn1GeneratorTests.pas',
Asn1SequenceParserTests in '..\src\Asn1\Asn1SequenceParserTests.pas',
+ Asn1SequenceCursorTests in '..\src\Asn1\Asn1SequenceCursorTests.pas',
Asn1TimeFormatTests in '..\src\Asn1\Asn1TimeFormatTests.pas',
BitStringTests in '..\src\Asn1\BitStringTests.pas',
DerUtf8StringTests in '..\src\Asn1\DerUtf8StringTests.pas',
@@ -883,6 +884,7 @@ uses
DigestRandomNumberTests in '..\src\Crypto\DigestRandomNumberTests.pas',
FixedPointTests in '..\src\Math\EC\FixedPointTests.pas',
AESTests in '..\src\Crypto\AESTests.pas',
+ BlockCipherTestBase in '..\src\Crypto\BlockCipherTestBase.pas',
AesBlockCipherTestBase in '..\src\Crypto\AesBlockCipherTestBase.pas',
AesLightTests in '..\src\Crypto\AesLightTests.pas',
FusedExternalRegistrationTests in '..\src\Crypto\FusedExternalRegistrationTests.pas',
diff --git a/CryptoLib.Tests/FreePascal.Tests/CryptoLib.Tests.lpi b/CryptoLib.Tests/FreePascal.Tests/CryptoLib.Tests.lpi
index aebb8170..4ec355e6 100644
--- a/CryptoLib.Tests/FreePascal.Tests/CryptoLib.Tests.lpi
+++ b/CryptoLib.Tests/FreePascal.Tests/CryptoLib.Tests.lpi
@@ -79,7 +79,7 @@
-
+
@@ -837,6 +837,14 @@
+
+
+
+
+
+
+
+
diff --git a/CryptoLib.Tests/FreePascal.Tests/CryptoLib.lpr b/CryptoLib.Tests/FreePascal.Tests/CryptoLib.lpr
index 19438c72..cf4d0936 100644
--- a/CryptoLib.Tests/FreePascal.Tests/CryptoLib.lpr
+++ b/CryptoLib.Tests/FreePascal.Tests/CryptoLib.lpr
@@ -4,6 +4,7 @@
uses
Interfaces, Forms, GuiTestRunner, Asn1GeneratorTests, Asn1SequenceParserTests,
+ Asn1SequenceCursorTests,
Asn1TimeFormatTests, EqualsAndHashCodeTests, OIDTests, EnumeratedTests,
ExternalTests, ParsingTests, ParseTests, StringTests, TagTests,
BigIntegerTests, ECAlgorithmsTests, ECPointTests, BinPolyTests,
@@ -12,7 +13,8 @@
DigestRandomNumberTests, FixedPointTests, AESTests, AesLightTests,
FusedExternalRegistrationTests, AesHardwareEngineTests, AESSICTests,
SicBulkParityTests, EcbBulkParityTests, CbcBulkParityTests,
- GcmSivBulkParityTests, SpeckBlockCipherTestBase, SpeckLegacyTests, SpeckTests,
+ GcmSivBulkParityTests, BlockCipherTestBase, SpeckBlockCipherTestBase,
+ SpeckLegacyTests, SpeckTests,
IESCipherTests, HMacTests, Pkcs5Tests, HkdfGeneratorTests, ECIESTests,
PascalCoinECIESTests, ECNRTests, PrimesTests, ECEncodingTests, GF256AesTests,
PaddingTests, DSATests, DeterministicDsaTests, Salsa20Tests, XSalsa20Tests,
diff --git a/CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.lpi b/CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.lpi
index d2d1e7eb..ce438b02 100644
--- a/CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.lpi
+++ b/CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.lpi
@@ -39,7 +39,7 @@
-
+
@@ -796,6 +796,14 @@
+
+
+
+
+
+
+
+
diff --git a/CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.lpr b/CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.lpr
index f4dc5434..059fb17a 100644
--- a/CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.lpr
+++ b/CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.lpr
@@ -5,6 +5,7 @@
uses
{$IFDEF UNIX}cwstring,{$ENDIF}
consoletestrunner, Asn1GeneratorTests, Asn1SequenceParserTests,
+ Asn1SequenceCursorTests,
Asn1TimeFormatTests, EqualsAndHashCodeTests, OIDTests, EnumeratedTests,
ExternalTests, ParsingTests, ParseTests, StringTests, TagTests,
BigIntegerTests, ECAlgorithmsTests, ECPointTests, BinPolyTests,
@@ -13,7 +14,8 @@
DigestRandomNumberTests, FixedPointTests, AESTests, AesLightTests,
FusedExternalRegistrationTests, AesHardwareEngineTests, AESSICTests,
SicBulkParityTests, EcbBulkParityTests, CbcBulkParityTests,
- GcmSivBulkParityTests, SpeckBlockCipherTestBase, SpeckLegacyTests, SpeckTests,
+ GcmSivBulkParityTests, BlockCipherTestBase, SpeckBlockCipherTestBase,
+ SpeckLegacyTests, SpeckTests,
IESCipherTests, HMacTests, Pkcs5Tests, HkdfGeneratorTests, ECIESTests,
PascalCoinECIESTests, ECNRTests, PrimesTests, ECEncodingTests, GF256AesTests,
PaddingTests, DSATests, DeterministicDsaTests, Salsa20Tests, XSalsa20Tests,
diff --git a/CryptoLib.Tests/src/Asn1/Asn1SequenceCursorTests.pas b/CryptoLib.Tests/src/Asn1/Asn1SequenceCursorTests.pas
new file mode 100644
index 00000000..82957d28
--- /dev/null
+++ b/CryptoLib.Tests/src/Asn1/Asn1SequenceCursorTests.pas
@@ -0,0 +1,232 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * 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 * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit Asn1SequenceCursorTests;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+ Classes,
+ SysUtils,
+{$IFDEF FPC}
+ fpcunit,
+ testregistry,
+{$ELSE}
+ TestFramework,
+{$ENDIF FPC}
+ ClpAsn1Objects,
+ ClpIAsn1Objects,
+ ClpIAsn1Core,
+ ClpAsn1Utilities,
+ ClpCryptoLibTypes,
+ CryptoLibTestBase;
+
+type
+
+ ///
+ /// Direct edge-case tests for the TAsn1Utilities sequence cursor helpers
+ /// (Read / ReadOptional / ReadContextTagged / CheckSequenceSize / RequireEndOfSequence).
+ ///
+ TTestAsn1SequenceCursor = class(TCryptoLibAlgorithmTestCase)
+ private
+ function IntSeq(const AValues: array of Int32): IAsn1Sequence;
+ published
+ procedure TestReadMandatoryAndRequireEnd;
+ procedure TestCheckSequenceSizeRejectsWrongSize;
+ procedure TestCheckSequenceSizeRejectsNil;
+ procedure TestReadRejectsPrematureEnd;
+ procedure TestRequireEndRejectsTrailing;
+ procedure TestReadEncodableReturnsRawElement;
+ procedure TestReadOptionalPresentAdvances;
+ procedure TestReadOptionalAbsentDoesNotAdvance;
+ procedure TestReadContextTaggedExplicit;
+ end;
+
+implementation
+
+function TTestAsn1SequenceCursor.IntSeq(const AValues: array of Int32): IAsn1Sequence;
+var
+ LElements: TCryptoLibGenericArray;
+ LI: Int32;
+begin
+ LElements := nil;
+ System.SetLength(LElements, System.Length(AValues));
+ for LI := 0 to System.Length(AValues) - 1 do
+ LElements[LI] := TDerInteger.ValueOf(AValues[LI]);
+ Result := TDerSequence.FromElements(LElements);
+end;
+
+procedure TTestAsn1SequenceCursor.TestReadMandatoryAndRequireEnd;
+var
+ LSeq: IAsn1Sequence;
+ LPos: Int32;
+ LA, LB: IDerInteger;
+begin
+ LSeq := IntSeq([7, 11]);
+ LPos := 0;
+ TAsn1Utilities.CheckSequenceSize(LSeq, 2, 2);
+ LA := TAsn1Utilities.Read(LSeq, LPos, TDerInteger.GetInstance);
+ LB := TAsn1Utilities.Read(LSeq, LPos, TDerInteger.GetInstance);
+ TAsn1Utilities.RequireEndOfSequence(LSeq, LPos);
+ CheckTrue(LA.HasValue(7), 'first element');
+ CheckTrue(LB.HasValue(11), 'second element');
+ CheckEquals(2, LPos, 'position after two reads');
+end;
+
+procedure TTestAsn1SequenceCursor.TestCheckSequenceSizeRejectsWrongSize;
+var
+ LRaised: Boolean;
+begin
+ LRaised := False;
+ try
+ TAsn1Utilities.CheckSequenceSize(IntSeq([1, 2, 3]), 2, 2);
+ except
+ on E: EArgumentCryptoLibException do
+ LRaised := True;
+ end;
+ CheckTrue(LRaised, 'expected bad-sequence-size exception');
+end;
+
+procedure TTestAsn1SequenceCursor.TestCheckSequenceSizeRejectsNil;
+var
+ LSeq: IAsn1Sequence;
+ LRaised: Boolean;
+begin
+ LSeq := nil;
+ LRaised := False;
+ try
+ TAsn1Utilities.CheckSequenceSize(LSeq, 0, 3);
+ except
+ on E: EArgumentNilCryptoLibException do
+ LRaised := True;
+ end;
+ CheckTrue(LRaised, 'expected nil-sequence exception');
+end;
+
+procedure TTestAsn1SequenceCursor.TestReadRejectsPrematureEnd;
+var
+ LSeq: IAsn1Sequence;
+ LPos: Int32;
+ LRaised: Boolean;
+begin
+ LSeq := IntSeq([1]);
+ LPos := 0;
+ TAsn1Utilities.Read(LSeq, LPos, TDerInteger.GetInstance);
+ LRaised := False;
+ try
+ TAsn1Utilities.Read(LSeq, LPos, TDerInteger.GetInstance);
+ except
+ on E: EArgumentCryptoLibException do
+ LRaised := True;
+ end;
+ CheckTrue(LRaised, 'expected premature-end exception');
+end;
+
+procedure TTestAsn1SequenceCursor.TestRequireEndRejectsTrailing;
+var
+ LSeq: IAsn1Sequence;
+ LPos: Int32;
+ LRaised: Boolean;
+begin
+ LSeq := IntSeq([1, 2]);
+ LPos := 0;
+ TAsn1Utilities.Read(LSeq, LPos, TDerInteger.GetInstance);
+ LRaised := False;
+ try
+ TAsn1Utilities.RequireEndOfSequence(LSeq, LPos);
+ except
+ on E: EArgumentCryptoLibException do
+ LRaised := True;
+ end;
+ CheckTrue(LRaised, 'expected unexpected-elements exception');
+end;
+
+procedure TTestAsn1SequenceCursor.TestReadEncodableReturnsRawElement;
+var
+ LSeq: IAsn1Sequence;
+ LPos: Int32;
+ LElement: IAsn1Encodable;
+begin
+ LSeq := IntSeq([42]);
+ LPos := 0;
+ LElement := TAsn1Utilities.ReadEncodable(LSeq, LPos);
+ CheckNotNull(LElement, 'raw element');
+ CheckEquals(1, LPos, 'position advanced');
+ CheckTrue(TDerInteger.GetInstance(LElement).HasValue(42), 'element value');
+end;
+
+procedure TTestAsn1SequenceCursor.TestReadOptionalPresentAdvances;
+var
+ LSeq: IAsn1Sequence;
+ LPos: Int32;
+ LValue: IDerInteger;
+begin
+ LSeq := IntSeq([9]);
+ LPos := 0;
+ LValue := TAsn1Utilities.ReadOptional(LSeq, LPos, TDerInteger.GetOptional);
+ CheckNotNull(LValue, 'optional present');
+ CheckTrue(LValue.HasValue(9), 'optional value');
+ CheckEquals(1, LPos, 'position advanced');
+end;
+
+procedure TTestAsn1SequenceCursor.TestReadOptionalAbsentDoesNotAdvance;
+var
+ LSeq: IAsn1Sequence;
+ LPos: Int32;
+ LBits: IDerBitString;
+ LInt: IDerInteger;
+begin
+ // sequence holds a DerInteger; an optional DerBitString read must not consume it
+ LSeq := IntSeq([5]);
+ LPos := 0;
+ LBits := TAsn1Utilities.ReadOptional(LSeq, LPos, TDerBitString.GetOptional);
+ CheckNull(LBits, 'optional absent');
+ CheckEquals(0, LPos, 'position not advanced');
+ LInt := TAsn1Utilities.Read(LSeq, LPos, TDerInteger.GetInstance);
+ CheckTrue(LInt.HasValue(5), 'element still readable');
+ CheckEquals(1, LPos, 'position advanced after mandatory read');
+end;
+
+procedure TTestAsn1SequenceCursor.TestReadContextTaggedExplicit;
+var
+ LSeq: IAsn1Sequence;
+ LPos: Int32;
+ LValue: IDerInteger;
+begin
+ LSeq := TDerSequence.FromElement(TDerTaggedObject.Create(True, 0, TDerInteger.ValueOf(5)) as IDerTaggedObject);
+ LPos := 0;
+ LValue := TAsn1Utilities.ReadContextTagged(LSeq, LPos, 0, True, TDerInteger.GetTagged);
+ TAsn1Utilities.RequireEndOfSequence(LSeq, LPos);
+ CheckNotNull(LValue, 'context-tagged value');
+ CheckTrue(LValue.HasValue(5), 'context-tagged value content');
+ CheckEquals(1, LPos, 'position advanced');
+end;
+
+initialization
+
+// Register any test cases with the test runner
+
+{$IFDEF FPC}
+ RegisterTest(TTestAsn1SequenceCursor);
+{$ELSE}
+ RegisterTest(TTestAsn1SequenceCursor.Suite);
+{$ENDIF FPC}
+
+end.
diff --git a/CryptoLib.Tests/src/Asn1/Asn1StreamReadTests.pas b/CryptoLib.Tests/src/Asn1/Asn1StreamReadTests.pas
index b1a961b9..483feae6 100644
--- a/CryptoLib.Tests/src/Asn1/Asn1StreamReadTests.pas
+++ b/CryptoLib.Tests/src/Asn1/Asn1StreamReadTests.pas
@@ -282,7 +282,7 @@ function TAsn1StreamReadTest.BuildBerIndefiniteConstructedBitString
procedure TAsn1StreamReadTest.TestConstructedOctetReadAllRoundTrip;
var
- LPayload, LEncoding, LActual: TCryptoLibByteArray;
+ LPayload, LEncoding: TCryptoLibByteArray;
LParser: IAsn1StreamParser;
LOctets: IBerOctetString;
LI: Int32;
diff --git a/CryptoLib.Tests/src/Crypto/AESTests.pas b/CryptoLib.Tests/src/Crypto/AESTests.pas
index af58be07..5378d03a 100644
--- a/CryptoLib.Tests/src/Crypto/AESTests.pas
+++ b/CryptoLib.Tests/src/Crypto/AESTests.pas
@@ -57,6 +57,7 @@ interface
FixedSecureRandom,
ClpCryptoLibTypes,
CryptoLibTestBase,
+ BlockCipherTestBase,
AesBlockCipherTestBase,
SymmetricBlockVectors;
@@ -107,11 +108,10 @@ TTestAES = class(TAesBlockCipherTestBase)
protected
procedure SetUp; override;
procedure TearDown; override;
+ function GetEngineFactory: TBlockCipherFactory; override;
+ function EngineLabel: String; override;
published
- procedure TestBlockCipherVector;
- procedure TestMonteCarloAES;
- procedure TestBadParameters;
procedure TestOids;
procedure TestCiphers;
procedure TestAES_CBC_PKCS7PADDING_WITH_IV;
@@ -449,19 +449,14 @@ procedure TTestAES.TearDown;
inherited;
end;
-procedure TTestAES.TestBlockCipherVector;
+function TTestAES.GetEngineFactory: TBlockCipherFactory;
begin
- RunBlockCipherVectorTests(@CreateAesEngine, 'TAesEngine');
+ Result := @CreateAesEngine;
end;
-procedure TTestAES.TestMonteCarloAES;
+function TTestAES.EngineLabel: String;
begin
- RunBlockCipherMonteCarloTests(@CreateAesEngine, 'TAesEngine');
-end;
-
-procedure TTestAES.TestBadParameters;
-begin
- AssertEngineRejectsBadParameters(@CreateAesEngine, 'TAesEngine');
+ Result := 'TAesEngine';
end;
procedure TTestAES.TestCiphers;
diff --git a/CryptoLib.Tests/src/Crypto/AesBlockCipherTestBase.pas b/CryptoLib.Tests/src/Crypto/AesBlockCipherTestBase.pas
index 30c43618..392b199d 100644
--- a/CryptoLib.Tests/src/Crypto/AesBlockCipherTestBase.pas
+++ b/CryptoLib.Tests/src/Crypto/AesBlockCipherTestBase.pas
@@ -34,16 +34,14 @@ interface
ClpIKeyParameter,
ClpKeyParameter,
ClpICipherParameters,
- ClpIParametersWithIV,
- ClpParametersWithIV,
ClpIBufferedBlockCipher,
ClpBufferedBlockCipher,
ClpCryptoLibTypes,
- CryptoLibTestBase;
+ CryptoLibTestBase,
+ BlockCipherTestBase;
type
-
- TAesBlockCipherTestBase = class abstract(TCryptoLibAlgorithmTestCase)
+ TAesBlockCipherTestBase = class abstract(TBlockCipherTestBase)
strict private
class var
FBlockCipherVectorKeys, FBlockCipherVectorInputs,
@@ -53,26 +51,23 @@ TAesBlockCipherTestBase = class abstract(TCryptoLibAlgorithmTestCase)
class constructor CreateBlockCipherTestData;
- procedure DoBlockCipherVectorTest(const AEngine: IBlockCipher;
- const AParam: ICipherParameters; const AInput, AOutput: String;
- const APreface: String = '');
-
procedure DoBlockCipherMonteCarloTest(const AIteration: String;
const AEngine: IBlockCipher; const AParam: ICipherParameters;
const AInput, AOutput: String; const APreface: String = '');
strict protected
- procedure RunBlockCipherVectorTests(const ACreateEngine
- : TCryptoLibFunc; const AEngineLabel: String);
+ // engine hooks supplied by the concrete suite
+ function GetEngineFactory: TBlockCipherFactory; virtual; abstract;
+ function EngineLabel: String; virtual; abstract;
+ // default: always run; hardware suites override with a real capability check
+ function EngineSupported: Boolean; virtual;
procedure RunBlockCipherMonteCarloTests(const ACreateEngine
- : TCryptoLibFunc; const AEngineLabel: String);
-
- procedure AssertEngineRejectsBadParameters(const ACreateEngine
- : TCryptoLibFunc; const AEngineLabel: String);
-
- procedure RunCipherEngineChecks(const AEngine: IBlockCipher;
- const AValidKey: IKeyParameter; const AContext: String);
+ : TBlockCipherFactory; const AEngineLabel: String);
+ published
+ procedure TestBlockCipherVector;
+ procedure TestMonteCarloAES;
+ procedure TestBadParameters;
end;
implementation
@@ -147,53 +142,6 @@ implementation
'E58B82BFBA53C0040DC610C642121168');
end;
-procedure TAesBlockCipherTestBase.DoBlockCipherVectorTest(const AEngine: IBlockCipher;
- const AParam: ICipherParameters; const AInput, AOutput: String;
- const APreface: String);
-var
- LCipher: IBufferedBlockCipher;
- LLen1, LLen2: Int32;
- LInput, LOutput, LOutBytes: TBytes;
- LPrefix: String;
-begin
- LInput := DecodeHex(AInput);
- LOutput := DecodeHex(AOutput);
-
- if APreface <> '' then
- LPrefix := '[' + APreface + '] '
- else
- LPrefix := '';
-
- LCipher := TBufferedBlockCipher.Create(AEngine);
-
- LCipher.Init(True, AParam);
-
- System.SetLength(LOutBytes, System.Length(LInput));
-
- LLen1 := LCipher.ProcessBytes(LInput, 0, System.Length(LInput), LOutBytes, 0);
-
- LCipher.DoFinal(LOutBytes, LLen1);
-
- if (not AreEqual(LOutBytes, LOutput)) then
- begin
- Fail(LPrefix + Format('Encryption Failed - Expected %s but got %s',
- [EncodeHex(LOutput), EncodeHex(LOutBytes)]));
- end;
-
- LCipher.Init(False, AParam);
-
- LLen2 := LCipher.ProcessBytes(LOutput, 0, System.Length(LOutput),
- LOutBytes, 0);
-
- LCipher.DoFinal(LOutBytes, LLen2);
-
- if (not AreEqual(LInput, LOutBytes)) then
- begin
- Fail(LPrefix + Format('Decryption Failed - Expected %s but got %s',
- [EncodeHex(LInput), EncodeHex(LOutBytes)]));
- end;
-end;
-
procedure TAesBlockCipherTestBase.DoBlockCipherMonteCarloTest(const AIteration: String;
const AEngine: IBlockCipher; const AParam: ICipherParameters;
const AInput, AOutput: String; const APreface: String);
@@ -256,25 +204,35 @@ procedure TAesBlockCipherTestBase.DoBlockCipherMonteCarloTest(const AIteration:
end;
end;
-procedure TAesBlockCipherTestBase.RunBlockCipherVectorTests(const ACreateEngine
- : TCryptoLibFunc; const AEngineLabel: String);
-var
- LI: Int32;
- LPreface: String;
+function TAesBlockCipherTestBase.EngineSupported: Boolean;
begin
- for LI := System.Low(FBlockCipherVectorKeys)
- to System.High(FBlockCipherVectorKeys) do
- begin
- LPreface := Format('%s block vector index %d', [AEngineLabel, LI]);
- DoBlockCipherVectorTest(ACreateEngine(),
- TKeyParameter.Create(DecodeHex(FBlockCipherVectorKeys[LI]))
- as IKeyParameter, FBlockCipherVectorInputs[LI],
- FBlockCipherVectorOutputs[LI], LPreface);
- end;
+ Result := True;
+end;
+
+procedure TAesBlockCipherTestBase.TestBlockCipherVector;
+begin
+ if not EngineSupported then
+ Exit;
+ RunBlockCipherVectorTests(GetEngineFactory(), EngineLabel,
+ FBlockCipherVectorKeys, FBlockCipherVectorInputs, FBlockCipherVectorOutputs);
+end;
+
+procedure TAesBlockCipherTestBase.TestMonteCarloAES;
+begin
+ if not EngineSupported then
+ Exit;
+ RunBlockCipherMonteCarloTests(GetEngineFactory(), EngineLabel);
+end;
+
+procedure TAesBlockCipherTestBase.TestBadParameters;
+begin
+ if not EngineSupported then
+ Exit;
+ AssertEngineRejectsBadParameters(GetEngineFactory(), EngineLabel);
end;
procedure TAesBlockCipherTestBase.RunBlockCipherMonteCarloTests(const ACreateEngine
- : TCryptoLibFunc; const AEngineLabel: String);
+ : TBlockCipherFactory; const AEngineLabel: String);
var
LI: Int32;
LPreface: String;
@@ -291,102 +249,4 @@ procedure TAesBlockCipherTestBase.RunBlockCipherMonteCarloTests(const ACreateEng
end;
end;
-procedure TAesBlockCipherTestBase.AssertEngineRejectsBadParameters(const ACreateEngine
- : TCryptoLibFunc; const AEngineLabel: String);
-var
- LDudKey, LIV: TBytes;
- LEngine: IBlockCipher;
-begin
- LEngine := ACreateEngine();
-
- try
- System.SetLength(LDudKey, 6);
- LEngine.Init(True, TKeyParameter.Create(LDudKey) as IKeyParameter);
- Fail(Format('[%s] failed key length check', [AEngineLabel]));
- except
- on e: EArgumentCryptoLibException do
- begin
- // expected
- end;
- end;
-
- LEngine := ACreateEngine();
-
- try
- System.SetLength(LIV, 16);
- LEngine.Init(True, TParametersWithIV.Create(nil, LIV) as IParametersWithIV);
- Fail(Format('[%s] failed parameter check', [AEngineLabel]));
- except
- on e: EArgumentCryptoLibException do
- begin
- // expected
- end;
- end;
-end;
-
-procedure TAesBlockCipherTestBase.RunCipherEngineChecks(const AEngine: IBlockCipher;
- const AValidKey: IKeyParameter; const AContext: String);
-var
- LCorrectBuf, LShortBuf: TBytes;
- LBlockSize: Int32;
-begin
- LBlockSize := AEngine.GetBlockSize();
- System.SetLength(LCorrectBuf, LBlockSize);
- System.SetLength(LShortBuf, LBlockSize div 2);
-
- try
- AEngine.ProcessBlock(LCorrectBuf, 0, LCorrectBuf, 0);
- Fail(Format('[%s] failed initialisation check', [AContext]));
- except
- on E: EInvalidOperationCryptoLibException do
- begin
- // expected
- end;
- end;
-
- AEngine.Init(True, AValidKey as ICipherParameters);
-
- try
- AEngine.ProcessBlock(LShortBuf, 0, LCorrectBuf, 0);
- Fail(Format('[%s] failed short input check (encrypt)', [AContext]));
- except
- on E: EDataLengthCryptoLibException do
- begin
- // expected (includes EOutputLengthCryptoLibException)
- end;
- end;
-
- try
- AEngine.ProcessBlock(LCorrectBuf, 0, LShortBuf, 0);
- Fail(Format('[%s] failed short output check (encrypt)', [AContext]));
- except
- on E: EDataLengthCryptoLibException do
- begin
- // expected
- end;
- end;
-
- AEngine.Init(False, AValidKey as ICipherParameters);
-
- try
- AEngine.ProcessBlock(LShortBuf, 0, LCorrectBuf, 0);
- Fail(Format('[%s] failed short input check (decrypt)', [AContext]));
- except
- on E: EDataLengthCryptoLibException do
- begin
- // expected
- end;
- end;
-
- try
- AEngine.ProcessBlock(LCorrectBuf, 0, LShortBuf, 0);
- Fail(Format('[%s] failed short output check (decrypt)', [AContext]));
- except
- on E: EDataLengthCryptoLibException do
- begin
- // expected
- end;
- end;
-end;
-
end.
diff --git a/CryptoLib.Tests/src/Crypto/AesHardwareEngineTests.pas b/CryptoLib.Tests/src/Crypto/AesHardwareEngineTests.pas
index 5930f3c4..f2a0b90e 100644
--- a/CryptoLib.Tests/src/Crypto/AesHardwareEngineTests.pas
+++ b/CryptoLib.Tests/src/Crypto/AesHardwareEngineTests.pas
@@ -37,10 +37,10 @@ interface
{$IFDEF CRYPTOLIB_X86_SIMD}
ClpAesEngineX86,
{$ENDIF CRYPTOLIB_X86_SIMD}
+ BlockCipherTestBase,
AesBlockCipherTestBase;
type
- TEngineFactory = function: IBlockCipher;
///
/// Engine-agnostic test suite for hardware-accelerated AES engines. All the
/// vector / Monte-Carlo / engine-check coverage plus the SIMD batch (4-/8-wide)
@@ -53,10 +53,9 @@ interface
TAesHardwareEngineTestBase = class abstract(TAesBlockCipherTestBase)
strict protected
// ---- architecture hooks (implemented by the concrete per-arch suite) ----
+ // GetEngineFactory / EngineLabel / EngineSupported are inherited from
+ // TAesBlockCipherTestBase; only CreateHwEngine is hardware-specific.
function CreateHwEngine: IAesHardwareEngine; virtual; abstract;
- function EngineSupported: Boolean; virtual; abstract;
- function EngineLabel: String; virtual; abstract;
- function GetEngineFactory: TEngineFactory; virtual; abstract;
// ---- shared SIMD test logic ----
procedure ImplTestFourBlocks(AForEncryption: Boolean; AKeySizeBytes: Int32);
@@ -66,8 +65,8 @@ TAesHardwareEngineTestBase = class abstract(TAesBlockCipherTestBase)
procedure ImplTestProcessFourBlocksMemoryLayouts(AKeySizeBytes: Int32);
procedure ImplTestProcessEightBlocksMemoryLayouts(AKeySizeBytes: Int32);
published
- procedure TestBlockCipherVectors;
- procedure TestMonteCarloAES;
+ // TestBlockCipherVector / TestMonteCarloAES / TestBadParameters are
+ // inherited from TAesBlockCipherTestBase (guarded by EngineSupported).
procedure TestEngineChecks128;
procedure TestEngineChecks192;
procedure TestEngineChecks256;
@@ -108,7 +107,7 @@ TTestAesX86 = class(TAesHardwareEngineTestBase)
function CreateHwEngine: IAesHardwareEngine; override;
function EngineSupported: Boolean; override;
function EngineLabel: String; override;
- function GetEngineFactory: TEngineFactory; override;
+ function GetEngineFactory: TBlockCipherFactory; override;
end;
{$ENDIF CRYPTOLIB_X86_SIMD}
@@ -540,20 +539,6 @@ procedure TAesHardwareEngineTestBase.ImplTestProcessEightBlocksMemoryLayouts(AKe
end;
end;
-procedure TAesHardwareEngineTestBase.TestBlockCipherVectors;
-begin
- if not EngineSupported then
- Exit;
- RunBlockCipherVectorTests(GetEngineFactory(), EngineLabel);
-end;
-
-procedure TAesHardwareEngineTestBase.TestMonteCarloAES;
-begin
- if not EngineSupported then
- Exit;
- RunBlockCipherMonteCarloTests(GetEngineFactory(), EngineLabel);
-end;
-
procedure TAesHardwareEngineTestBase.TestEngineChecks128;
var
LKey: TBytes;
@@ -788,7 +773,7 @@ function TTestAesX86.EngineLabel: String;
Result := 'TAesEngineX86';
end;
-function TTestAesX86.GetEngineFactory: TEngineFactory;
+function TTestAesX86.GetEngineFactory: TBlockCipherFactory;
begin
Result := @CreateAesX86Engine;
end;
diff --git a/CryptoLib.Tests/src/Crypto/AesLightTests.pas b/CryptoLib.Tests/src/Crypto/AesLightTests.pas
index 070d3db1..477e2415 100644
--- a/CryptoLib.Tests/src/Crypto/AesLightTests.pas
+++ b/CryptoLib.Tests/src/Crypto/AesLightTests.pas
@@ -31,15 +31,15 @@ interface
{$ENDIF FPC}
ClpAesLightEngine,
ClpIBlockCipher,
+ BlockCipherTestBase,
AesBlockCipherTestBase;
type
TTestAesLight = class(TAesBlockCipherTestBase)
- published
- procedure TestBlockCipherVector;
- procedure TestMonteCarloAES;
- procedure TestBadParameters;
+ strict protected
+ function GetEngineFactory: TBlockCipherFactory; override;
+ function EngineLabel: String; override;
end;
implementation
@@ -51,19 +51,14 @@ function CreateAesLightEngine: IBlockCipher;
{ TTestAesLight }
-procedure TTestAesLight.TestBlockCipherVector;
+function TTestAesLight.GetEngineFactory: TBlockCipherFactory;
begin
- RunBlockCipherVectorTests(@CreateAesLightEngine, 'TAesLightEngine');
+ Result := @CreateAesLightEngine;
end;
-procedure TTestAesLight.TestMonteCarloAES;
+function TTestAesLight.EngineLabel: String;
begin
- RunBlockCipherMonteCarloTests(@CreateAesLightEngine, 'TAesLightEngine');
-end;
-
-procedure TTestAesLight.TestBadParameters;
-begin
- AssertEngineRejectsBadParameters(@CreateAesLightEngine, 'TAesLightEngine');
+ Result := 'TAesLightEngine';
end;
initialization
diff --git a/CryptoLib.Tests/src/Crypto/BlockCipherTestBase.pas b/CryptoLib.Tests/src/Crypto/BlockCipherTestBase.pas
new file mode 100644
index 00000000..03aabd4b
--- /dev/null
+++ b/CryptoLib.Tests/src/Crypto/BlockCipherTestBase.pas
@@ -0,0 +1,231 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * 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 * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit BlockCipherTestBase;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+ SysUtils,
+ ClpIBlockCipher,
+ ClpICipherParameters,
+ ClpIKeyParameter,
+ ClpKeyParameter,
+ ClpIParametersWithIV,
+ ClpParametersWithIV,
+ ClpIBufferedBlockCipher,
+ ClpBufferedBlockCipher,
+ ClpCryptoLibTypes,
+ CryptoLibTestBase;
+
+type
+ // shared factory shape for every block-cipher test suite
+ TBlockCipherFactory = function: IBlockCipher;
+
+ ///
+ /// Common scaffolding for block-cipher known-answer test suites: a single
+ /// encrypt/decrypt round-trip primitive and a data-driven runner over
+ /// parallel key/input/output vectors. Family-specific bases (AES, Speck)
+ /// inherit from this.
+ ///
+ TBlockCipherTestBase = class abstract(TCryptoLibAlgorithmTestCase)
+ strict protected
+ procedure DoBlockCipherVectorTest(const AEngine: IBlockCipher;
+ const AParam: ICipherParameters; const AInput, AOutput: String;
+ const APreface: String = '');
+
+ procedure RunBlockCipherVectorTests(const ACreateEngine: TBlockCipherFactory;
+ const AEngineLabel: String;
+ const AKeys, AInputs, AOutputs: TCryptoLibStringArray);
+
+ // engine-agnostic IBlockCipher contract checks
+ procedure AssertEngineRejectsBadParameters(const ACreateEngine
+ : TBlockCipherFactory; const AEngineLabel: String);
+
+ procedure RunCipherEngineChecks(const AEngine: IBlockCipher;
+ const AValidKey: IKeyParameter; const AContext: String);
+ end;
+
+implementation
+
+{ TBlockCipherTestBase }
+
+procedure TBlockCipherTestBase.DoBlockCipherVectorTest(const AEngine: IBlockCipher;
+ const AParam: ICipherParameters; const AInput, AOutput: String;
+ const APreface: String);
+var
+ LCipher: IBufferedBlockCipher;
+ LLen1, LLen2: Int32;
+ LInput, LOutput, LOutBytes: TBytes;
+ LPrefix: String;
+begin
+ LInput := DecodeHex(AInput);
+ LOutput := DecodeHex(AOutput);
+
+ if APreface <> '' then
+ LPrefix := '[' + APreface + '] '
+ else
+ LPrefix := '';
+
+ LCipher := TBufferedBlockCipher.Create(AEngine);
+
+ LCipher.Init(True, AParam);
+
+ System.SetLength(LOutBytes, System.Length(LInput));
+
+ LLen1 := LCipher.ProcessBytes(LInput, 0, System.Length(LInput), LOutBytes, 0);
+
+ LCipher.DoFinal(LOutBytes, LLen1);
+
+ if (not AreEqual(LOutBytes, LOutput)) then
+ begin
+ Fail(LPrefix + Format('Encryption Failed - Expected %s but got %s',
+ [EncodeHex(LOutput), EncodeHex(LOutBytes)]));
+ end;
+
+ LCipher.Init(False, AParam);
+
+ LLen2 := LCipher.ProcessBytes(LOutput, 0, System.Length(LOutput),
+ LOutBytes, 0);
+
+ LCipher.DoFinal(LOutBytes, LLen2);
+
+ if (not AreEqual(LInput, LOutBytes)) then
+ begin
+ Fail(LPrefix + Format('Decryption Failed - Expected %s but got %s',
+ [EncodeHex(LInput), EncodeHex(LOutBytes)]));
+ end;
+end;
+
+procedure TBlockCipherTestBase.RunBlockCipherVectorTests(const ACreateEngine
+ : TBlockCipherFactory; const AEngineLabel: String;
+ const AKeys, AInputs, AOutputs: TCryptoLibStringArray);
+var
+ LI: Int32;
+ LPreface: String;
+begin
+ for LI := System.Low(AKeys) to System.High(AKeys) do
+ begin
+ LPreface := Format('%s block vector index %d', [AEngineLabel, LI]);
+ DoBlockCipherVectorTest(ACreateEngine(),
+ TKeyParameter.Create(DecodeHex(AKeys[LI])) as IKeyParameter,
+ AInputs[LI], AOutputs[LI], LPreface);
+ end;
+end;
+
+procedure TBlockCipherTestBase.AssertEngineRejectsBadParameters(const ACreateEngine
+ : TBlockCipherFactory; const AEngineLabel: String);
+var
+ LDudKey, LIV: TBytes;
+ LEngine: IBlockCipher;
+begin
+ LEngine := ACreateEngine();
+
+ try
+ System.SetLength(LDudKey, 6);
+ LEngine.Init(True, TKeyParameter.Create(LDudKey) as IKeyParameter);
+ Fail(Format('[%s] failed key length check', [AEngineLabel]));
+ except
+ on e: EArgumentCryptoLibException do
+ begin
+ // expected
+ end;
+ end;
+
+ LEngine := ACreateEngine();
+
+ try
+ System.SetLength(LIV, 16);
+ LEngine.Init(True, TParametersWithIV.Create(nil, LIV) as IParametersWithIV);
+ Fail(Format('[%s] failed parameter check', [AEngineLabel]));
+ except
+ on e: EArgumentCryptoLibException do
+ begin
+ // expected
+ end;
+ end;
+end;
+
+procedure TBlockCipherTestBase.RunCipherEngineChecks(const AEngine: IBlockCipher;
+ const AValidKey: IKeyParameter; const AContext: String);
+var
+ LCorrectBuf, LShortBuf: TBytes;
+ LBlockSize: Int32;
+begin
+ LBlockSize := AEngine.GetBlockSize();
+ System.SetLength(LCorrectBuf, LBlockSize);
+ System.SetLength(LShortBuf, LBlockSize div 2);
+
+ try
+ AEngine.ProcessBlock(LCorrectBuf, 0, LCorrectBuf, 0);
+ Fail(Format('[%s] failed initialisation check', [AContext]));
+ except
+ on E: EInvalidOperationCryptoLibException do
+ begin
+ // expected
+ end;
+ end;
+
+ AEngine.Init(True, AValidKey as ICipherParameters);
+
+ try
+ AEngine.ProcessBlock(LShortBuf, 0, LCorrectBuf, 0);
+ Fail(Format('[%s] failed short input check (encrypt)', [AContext]));
+ except
+ on E: EDataLengthCryptoLibException do
+ begin
+ // expected (includes EOutputLengthCryptoLibException)
+ end;
+ end;
+
+ try
+ AEngine.ProcessBlock(LCorrectBuf, 0, LShortBuf, 0);
+ Fail(Format('[%s] failed short output check (encrypt)', [AContext]));
+ except
+ on E: EDataLengthCryptoLibException do
+ begin
+ // expected
+ end;
+ end;
+
+ AEngine.Init(False, AValidKey as ICipherParameters);
+
+ try
+ AEngine.ProcessBlock(LShortBuf, 0, LCorrectBuf, 0);
+ Fail(Format('[%s] failed short input check (decrypt)', [AContext]));
+ except
+ on E: EDataLengthCryptoLibException do
+ begin
+ // expected
+ end;
+ end;
+
+ try
+ AEngine.ProcessBlock(LCorrectBuf, 0, LShortBuf, 0);
+ Fail(Format('[%s] failed short output check (decrypt)', [AContext]));
+ except
+ on E: EDataLengthCryptoLibException do
+ begin
+ // expected
+ end;
+ end;
+end;
+
+end.
diff --git a/CryptoLib.Tests/src/Crypto/CbcBulkParityTests.pas b/CryptoLib.Tests/src/Crypto/CbcBulkParityTests.pas
index 92ea1768..d3a075ae 100644
--- a/CryptoLib.Tests/src/Crypto/CbcBulkParityTests.pas
+++ b/CryptoLib.Tests/src/Crypto/CbcBulkParityTests.pas
@@ -44,7 +44,8 @@ interface
ClpSecureRandom,
ClpISecureRandom,
ClpCryptoLibTypes,
- CryptoLibTestBase;
+ CryptoLibTestBase,
+ BlockCipherTestBase;
type
///
@@ -61,10 +62,7 @@ interface
///
TTestCbcBulkParity = class(TCryptoLibAlgorithmTestCase)
strict private
- type
- TEngineFactory = function: IBlockCipher;
-
- procedure RunParityForEngine(AEngineFactory: TEngineFactory;
+ procedure RunParityForEngine(AEngineFactory: TBlockCipherFactory;
AKeyLen, ABlockSize: Int32; const ALabel: String);
published
{$IFDEF CRYPTOLIB_X86_SIMD}
@@ -95,7 +93,7 @@ function CreateBlowfishEngine: IBlockCipher;
{ TTestCbcBulkParity }
-procedure TTestCbcBulkParity.RunParityForEngine(AEngineFactory: TEngineFactory;
+procedure TTestCbcBulkParity.RunParityForEngine(AEngineFactory: TBlockCipherFactory;
AKeyLen, ABlockSize: Int32; const ALabel: String);
const
BlockCounts: array [0 .. 15] of Int32 = (1, 2, 3, 4, 5, 7, 8, 9, 11, 12, 15,
diff --git a/CryptoLib.Tests/src/Crypto/EcbBulkParityTests.pas b/CryptoLib.Tests/src/Crypto/EcbBulkParityTests.pas
index 16068669..b94ec8c6 100644
--- a/CryptoLib.Tests/src/Crypto/EcbBulkParityTests.pas
+++ b/CryptoLib.Tests/src/Crypto/EcbBulkParityTests.pas
@@ -43,7 +43,8 @@ interface
ClpSecureRandom,
ClpISecureRandom,
ClpCryptoLibTypes,
- CryptoLibTestBase;
+ CryptoLibTestBase,
+ BlockCipherTestBase;
type
///
@@ -57,10 +58,7 @@ interface
///
TTestEcbBulkParity = class(TCryptoLibAlgorithmTestCase)
strict private
- type
- TEngineFactory = function: IBlockCipher;
-
- procedure RunParityForEngine(AEngineFactory: TEngineFactory;
+ procedure RunParityForEngine(AEngineFactory: TBlockCipherFactory;
AKeyLen, ABlockSize: Int32; const ALabel: String);
published
{$IFDEF CRYPTOLIB_X86_SIMD}
@@ -91,7 +89,7 @@ function CreateBlowfishEngine: IBlockCipher;
{ TTestEcbBulkParity }
-procedure TTestEcbBulkParity.RunParityForEngine(AEngineFactory: TEngineFactory;
+procedure TTestEcbBulkParity.RunParityForEngine(AEngineFactory: TBlockCipherFactory;
AKeyLen, ABlockSize: Int32; const ALabel: String);
const
BlockCounts: array [0 .. 15] of Int32 = (1, 2, 3, 4, 5, 7, 8, 9, 11, 12, 15,
diff --git a/CryptoLib.Tests/src/Crypto/SicBulkParityTests.pas b/CryptoLib.Tests/src/Crypto/SicBulkParityTests.pas
index d24d64cf..dea329c8 100644
--- a/CryptoLib.Tests/src/Crypto/SicBulkParityTests.pas
+++ b/CryptoLib.Tests/src/Crypto/SicBulkParityTests.pas
@@ -44,7 +44,8 @@ interface
ClpSecureRandom,
ClpISecureRandom,
ClpCryptoLibTypes,
- CryptoLibTestBase;
+ CryptoLibTestBase,
+ BlockCipherTestBase;
type
///
@@ -59,10 +60,7 @@ interface
///
TTestSicBulkParity = class(TCryptoLibAlgorithmTestCase)
strict private
- type
- TEngineFactory = function: IBlockCipher;
-
- procedure RunParityForEngine(AEngineFactory: TEngineFactory;
+ procedure RunParityForEngine(AEngineFactory: TBlockCipherFactory;
AKeyLen, AIvLen, ABlockSize: Int32; const ALabel: String);
published
{$IFDEF CRYPTOLIB_X86_SIMD}
@@ -97,7 +95,7 @@ function CreateBlowfishEngine: IBlockCipher;
{ TTestSicBulkParity }
-procedure TTestSicBulkParity.RunParityForEngine(AEngineFactory: TEngineFactory;
+procedure TTestSicBulkParity.RunParityForEngine(AEngineFactory: TBlockCipherFactory;
AKeyLen, AIvLen, ABlockSize: Int32; const ALabel: String);
const
// Chosen to stress every branch of the bulk dispatch:
diff --git a/CryptoLib.Tests/src/Crypto/SpeckBlockCipherTestBase.pas b/CryptoLib.Tests/src/Crypto/SpeckBlockCipherTestBase.pas
index a4c08a35..be096482 100644
--- a/CryptoLib.Tests/src/Crypto/SpeckBlockCipherTestBase.pas
+++ b/CryptoLib.Tests/src/Crypto/SpeckBlockCipherTestBase.pas
@@ -38,35 +38,22 @@ interface
ClpSicBlockCipher,
ClpISicBlockCipher,
ClpSpeckEngine,
- ClpISpeckEngine,
- ClpISpeckLegacyEngine,
ClpCryptoLibTypes,
CryptoLibTestBase,
+ BlockCipherTestBase,
SymmetricBlockVectors;
type
- TSpeckBlockCipherTestBase = class abstract(TCryptoLibAlgorithmTestCase)
+ TSpeckBlockCipherTestBase = class abstract(TBlockCipherTestBase)
strict private
- procedure DoBlockCipherVectorTest(const AEngine: IBlockCipher;
- const AParam: ICipherParameters; const AInput, AOutput: String;
- const APreface: String = '');
-
procedure DoSPECKTest(const ACipher: IBufferedCipher;
const AParam: ICipherParameters; const AInput, AOutput: String;
AWithPadding: Boolean = False);
strict protected
- procedure RunSpeckBlockCipherVectorTests(const ACreateEngine
- : TCryptoLibFunc; const AEngineLabel: String;
- const AKeys, AInputs, AOutputs: TCryptoLibStringArray);
-
- procedure RunSpeckLegacyBlockCipherVectorTests(const ACreateEngine
- : TCryptoLibFunc; const AEngineLabel: String;
- const AKeys, AInputs, AOutputs: TCryptoLibStringArray);
-
procedure RunCryptoPPSpeckModeTests(const AMode: string; AWithIV: Boolean;
- ACreateEngine: TCryptoLibFunc);
+ ACreateEngine: TBlockCipherFactory);
procedure RunCryptoPPSpeck64EcbTests;
procedure RunCryptoPPSpeck128EcbTests;
@@ -78,66 +65,18 @@ TSpeckBlockCipherTestBase = class abstract(TCryptoLibAlgorithmTestCase)
implementation
-function CreateSpeck64EngineForCryptoPP: ISpeckEngine;
+function CreateSpeck64EngineForCryptoPP: IBlockCipher;
begin
Result := TSpeck64Engine.Create();
end;
-function CreateSpeck128EngineForCryptoPP: ISpeckEngine;
+function CreateSpeck128EngineForCryptoPP: IBlockCipher;
begin
Result := TSpeck128Engine.Create();
end;
{ TSpeckBlockCipherTestBase }
-procedure TSpeckBlockCipherTestBase.DoBlockCipherVectorTest(const AEngine: IBlockCipher;
- const AParam: ICipherParameters; const AInput, AOutput: String;
- const APreface: String);
-var
- LCipher: IBufferedBlockCipher;
- LLen1, LLen2: Int32;
- LInput, LOutput, LOutBytes: TBytes;
- LPrefix: String;
-begin
- LInput := DecodeHex(AInput);
- LOutput := DecodeHex(AOutput);
-
- if APreface <> '' then
- LPrefix := '[' + APreface + '] '
- else
- LPrefix := '';
-
- LCipher := TBufferedBlockCipher.Create(AEngine);
-
- LCipher.Init(True, AParam);
-
- System.SetLength(LOutBytes, System.Length(LInput));
-
- LLen1 := LCipher.ProcessBytes(LInput, 0, System.Length(LInput),
- LOutBytes, 0);
-
- LCipher.DoFinal(LOutBytes, LLen1);
-
- if (not AreEqual(LOutBytes, LOutput)) then
- begin
- Fail(LPrefix + Format('Encryption Failed - Expected %s but got %s',
- [EncodeHex(LOutput), EncodeHex(LOutBytes)]));
- end;
-
- LCipher.Init(False, AParam);
-
- LLen2 := LCipher.ProcessBytes(LOutput, 0, System.Length(LOutput),
- LOutBytes, 0);
-
- LCipher.DoFinal(LOutBytes, LLen2);
-
- if (not AreEqual(LInput, LOutBytes)) then
- begin
- Fail(LPrefix + Format('Decryption Failed - Expected %s but got %s',
- [EncodeHex(LInput), EncodeHex(LOutBytes)]));
- end;
-end;
-
procedure TSpeckBlockCipherTestBase.DoSPECKTest(const ACipher: IBufferedCipher;
const AParam: ICipherParameters; const AInput, AOutput: String;
AWithPadding: Boolean);
@@ -171,40 +110,8 @@ procedure TSpeckBlockCipherTestBase.DoSPECKTest(const ACipher: IBufferedCipher;
end;
end;
-procedure TSpeckBlockCipherTestBase.RunSpeckBlockCipherVectorTests(const ACreateEngine
- : TCryptoLibFunc; const AEngineLabel: String;
- const AKeys, AInputs, AOutputs: TCryptoLibStringArray);
-var
- LI: Int32;
- LPreface: String;
-begin
- for LI := System.Low(AKeys) to System.High(AKeys) do
- begin
- LPreface := Format('%s block vector index %d', [AEngineLabel, LI]);
- DoBlockCipherVectorTest(ACreateEngine(),
- TKeyParameter.Create(DecodeHex(AKeys[LI])) as IKeyParameter,
- AInputs[LI], AOutputs[LI], LPreface);
- end;
-end;
-
-procedure TSpeckBlockCipherTestBase.RunSpeckLegacyBlockCipherVectorTests(const ACreateEngine
- : TCryptoLibFunc; const AEngineLabel: String;
- const AKeys, AInputs, AOutputs: TCryptoLibStringArray);
-var
- LI: Int32;
- LPreface: String;
-begin
- for LI := System.Low(AKeys) to System.High(AKeys) do
- begin
- LPreface := Format('%s block vector index %d', [AEngineLabel, LI]);
- DoBlockCipherVectorTest(ACreateEngine(),
- TKeyParameter.Create(DecodeHex(AKeys[LI])) as IKeyParameter,
- AInputs[LI], AOutputs[LI], LPreface);
- end;
-end;
-
procedure TSpeckBlockCipherTestBase.RunCryptoPPSpeckModeTests(const AMode: string;
- AWithIV: Boolean; ACreateEngine: TCryptoLibFunc);
+ AWithIV: Boolean; ACreateEngine: TBlockCipherFactory);
var
LRows: TCryptoLibGenericArray;
LKeyParametersWithIV: IParametersWithIV;
@@ -212,7 +119,7 @@ procedure TSpeckBlockCipherTestBase.RunCryptoPPSpeckModeTests(const AMode: strin
LKeyBytes, LIVBytes: TBytes;
LCipher: IBufferedCipher;
LI: Int32;
- LEngine: ISpeckEngine;
+ LEngine: IBlockCipher;
LBlockCipher: IBlockCipher;
LCbcBlockCipher: ICbcBlockCipher;
LSicBlockCipher: ISicBlockCipher;
diff --git a/CryptoLib.Tests/src/Crypto/SpeckLegacyTests.pas b/CryptoLib.Tests/src/Crypto/SpeckLegacyTests.pas
index 0d7c8c57..818ee668 100644
--- a/CryptoLib.Tests/src/Crypto/SpeckLegacyTests.pas
+++ b/CryptoLib.Tests/src/Crypto/SpeckLegacyTests.pas
@@ -30,7 +30,7 @@ interface
TestFramework,
{$ENDIF FPC}
ClpSpeckLegacyEngine,
- ClpISpeckLegacyEngine,
+ ClpIBlockCipher,
ClpCryptoLibTypes,
SpeckBlockCipherTestBase;
@@ -74,27 +74,27 @@ TTestSpeckLegacy = class(TSpeckBlockCipherTestBase)
implementation
-function CreateSpeck32LegacyEngine: ISpeckLegacyEngine;
+function CreateSpeck32LegacyEngine: IBlockCipher;
begin
Result := TSpeck32LegacyEngine.Create();
end;
-function CreateSpeck48LegacyEngine: ISpeckLegacyEngine;
+function CreateSpeck48LegacyEngine: IBlockCipher;
begin
Result := TSpeck48LegacyEngine.Create();
end;
-function CreateSpeck64LegacyEngine: ISpeckLegacyEngine;
+function CreateSpeck64LegacyEngine: IBlockCipher;
begin
Result := TSpeck64LegacyEngine.Create();
end;
-function CreateSpeck96LegacyEngine: ISpeckLegacyEngine;
+function CreateSpeck96LegacyEngine: IBlockCipher;
begin
Result := TSpeck96LegacyEngine.Create();
end;
-function CreateSpeck128LegacyEngine: ISpeckLegacyEngine;
+function CreateSpeck128LegacyEngine: IBlockCipher;
begin
Result := TSpeck128LegacyEngine.Create();
end;
@@ -165,7 +165,7 @@ procedure TTestSpeckLegacy.TearDown;
procedure TTestSpeckLegacy.TestBlockCipherVectorSpeck32;
begin
- RunSpeckLegacyBlockCipherVectorTests(@CreateSpeck32LegacyEngine,
+ RunBlockCipherVectorTests(@CreateSpeck32LegacyEngine,
'TSpeck32LegacyEngine', FSpeck32LegacyBlockCipherVectorKeys,
FSpeck32LegacyBlockCipherVectorInputs,
FSpeck32LegacyBlockCipherVectorOutputs);
@@ -173,7 +173,7 @@ procedure TTestSpeckLegacy.TestBlockCipherVectorSpeck32;
procedure TTestSpeckLegacy.TestBlockCipherVectorSpeck48;
begin
- RunSpeckLegacyBlockCipherVectorTests(@CreateSpeck48LegacyEngine,
+ RunBlockCipherVectorTests(@CreateSpeck48LegacyEngine,
'TSpeck48LegacyEngine', FSpeck48LegacyBlockCipherVectorKeys,
FSpeck48LegacyBlockCipherVectorInputs,
FSpeck48LegacyBlockCipherVectorOutputs);
@@ -181,7 +181,7 @@ procedure TTestSpeckLegacy.TestBlockCipherVectorSpeck48;
procedure TTestSpeckLegacy.TestBlockCipherVectorSpeck64;
begin
- RunSpeckLegacyBlockCipherVectorTests(@CreateSpeck64LegacyEngine,
+ RunBlockCipherVectorTests(@CreateSpeck64LegacyEngine,
'TSpeck64LegacyEngine', FSpeck64LegacyBlockCipherVectorKeys,
FSpeck64LegacyBlockCipherVectorInputs,
FSpeck64LegacyBlockCipherVectorOutputs);
@@ -189,7 +189,7 @@ procedure TTestSpeckLegacy.TestBlockCipherVectorSpeck64;
procedure TTestSpeckLegacy.TestBlockCipherVectorSpeck96;
begin
- RunSpeckLegacyBlockCipherVectorTests(@CreateSpeck96LegacyEngine,
+ RunBlockCipherVectorTests(@CreateSpeck96LegacyEngine,
'TSpeck96LegacyEngine', FSpeck96LegacyBlockCipherVectorKeys,
FSpeck96LegacyBlockCipherVectorInputs,
FSpeck96LegacyBlockCipherVectorOutputs);
@@ -197,7 +197,7 @@ procedure TTestSpeckLegacy.TestBlockCipherVectorSpeck96;
procedure TTestSpeckLegacy.TestBlockCipherVectorSpeck128;
begin
- RunSpeckLegacyBlockCipherVectorTests(@CreateSpeck128LegacyEngine,
+ RunBlockCipherVectorTests(@CreateSpeck128LegacyEngine,
'TSpeck128LegacyEngine', FSpeck128LegacyBlockCipherVectorKeys,
FSpeck128LegacyBlockCipherVectorInputs,
FSpeck128LegacyBlockCipherVectorOutputs);
diff --git a/CryptoLib.Tests/src/Crypto/SpeckTests.pas b/CryptoLib.Tests/src/Crypto/SpeckTests.pas
index c4b88215..7650b5ac 100644
--- a/CryptoLib.Tests/src/Crypto/SpeckTests.pas
+++ b/CryptoLib.Tests/src/Crypto/SpeckTests.pas
@@ -30,7 +30,7 @@ interface
TestFramework,
{$ENDIF FPC}
ClpSpeckEngine,
- ClpISpeckEngine,
+ ClpIBlockCipher,
ClpCryptoLibTypes,
SpeckBlockCipherTestBase;
@@ -75,27 +75,27 @@ TTestSpeck = class(TSpeckBlockCipherTestBase)
implementation
-function CreateSpeck32Engine: ISpeckEngine;
+function CreateSpeck32Engine: IBlockCipher;
begin
Result := TSpeck32Engine.Create();
end;
-function CreateSpeck48Engine: ISpeckEngine;
+function CreateSpeck48Engine: IBlockCipher;
begin
Result := TSpeck48Engine.Create();
end;
-function CreateSpeck64Engine: ISpeckEngine;
+function CreateSpeck64Engine: IBlockCipher;
begin
Result := TSpeck64Engine.Create();
end;
-function CreateSpeck96Engine: ISpeckEngine;
+function CreateSpeck96Engine: IBlockCipher;
begin
Result := TSpeck96Engine.Create();
end;
-function CreateSpeck128Engine: ISpeckEngine;
+function CreateSpeck128Engine: IBlockCipher;
begin
Result := TSpeck128Engine.Create();
end;
@@ -164,35 +164,35 @@ procedure TTestSpeck.TearDown;
procedure TTestSpeck.TestBlockCipherVectorSpeck32;
begin
- RunSpeckBlockCipherVectorTests(@CreateSpeck32Engine, 'TSpeck32Engine',
+ RunBlockCipherVectorTests(@CreateSpeck32Engine, 'TSpeck32Engine',
FSpeck32BlockCipherVectorKeys, FSpeck32BlockCipherVectorInputs,
FSpeck32BlockCipherVectorOutputs);
end;
procedure TTestSpeck.TestBlockCipherVectorSpeck48;
begin
- RunSpeckBlockCipherVectorTests(@CreateSpeck48Engine, 'TSpeck48Engine',
+ RunBlockCipherVectorTests(@CreateSpeck48Engine, 'TSpeck48Engine',
FSpeck48BlockCipherVectorKeys, FSpeck48BlockCipherVectorInputs,
FSpeck48BlockCipherVectorOutputs);
end;
procedure TTestSpeck.TestBlockCipherVectorSpeck64;
begin
- RunSpeckBlockCipherVectorTests(@CreateSpeck64Engine, 'TSpeck64Engine',
+ RunBlockCipherVectorTests(@CreateSpeck64Engine, 'TSpeck64Engine',
FSpeck64BlockCipherVectorKeys, FSpeck64BlockCipherVectorInputs,
FSpeck64BlockCipherVectorOutputs);
end;
procedure TTestSpeck.TestBlockCipherVectorSpeck96;
begin
- RunSpeckBlockCipherVectorTests(@CreateSpeck96Engine, 'TSpeck96Engine',
+ RunBlockCipherVectorTests(@CreateSpeck96Engine, 'TSpeck96Engine',
FSpeck96BlockCipherVectorKeys, FSpeck96BlockCipherVectorInputs,
FSpeck96BlockCipherVectorOutputs);
end;
procedure TTestSpeck.TestBlockCipherVectorSpeck128;
begin
- RunSpeckBlockCipherVectorTests(@CreateSpeck128Engine, 'TSpeck128Engine',
+ RunBlockCipherVectorTests(@CreateSpeck128Engine, 'TSpeck128Engine',
FSpeck128BlockCipherVectorKeys, FSpeck128BlockCipherVectorInputs,
FSpeck128BlockCipherVectorOutputs);
end;
diff --git a/CryptoLib/src/Asn1/ClpAsn1Utilities.pas b/CryptoLib/src/Asn1/ClpAsn1Utilities.pas
index 996d1996..8cb231c2 100644
--- a/CryptoLib/src/Asn1/ClpAsn1Utilities.pas
+++ b/CryptoLib/src/Asn1/ClpAsn1Utilities.pas
@@ -36,8 +36,17 @@ interface
SExpectedTagButFound = 'expected %s tag but found %s';
SFailedToConstructFromByte = 'failed to construct %s from byte array: %s';
SInvalidObject = 'invalid object: %s';
+ SSequenceNil = 'sequence cannot be nil';
+ SBadSequenceSize = 'bad sequence size: %d';
+ SPrematureEndOfSequence = 'premature end of sequence';
+ SUnexpectedElementsInSequence = 'unexpected elements in sequence';
type
+ // sequence-cursor constructor callbacks
+ TAsn1Constructor = function(const AElement: TInput): TResult;
+ TAsn1TaggedConstructor = function(const ATagged: IAsn1TaggedObject;
+ ADeclaredExplicit: Boolean): TResult;
+
///
/// Utility class for ASN.1 operations.
///
@@ -81,6 +90,15 @@ TAsn1Utilities = class sealed(TObject)
class function GetTaggedChoice(const ATaggedObject: IAsn1TaggedObject;
ADeclaredExplicit: Boolean; const AConstructor: TCryptoLibFunc): TChoice; static;
+ // Cursor callback: [n] EXPLICIT base object
+ class function GetTaggedExplicitBaseObject(const ATaggedObject: IAsn1TaggedObject;
+ ADeclaredExplicit: Boolean): IAsn1Encodable; static;
+ // Cursor callback: the tagged object itself
+ class function GetTaggedObjectIdentity(const ATaggedObject: IAsn1TaggedObject;
+ ADeclaredExplicit: Boolean): IAsn1TaggedObject; static;
+ // Cursor callback: the element itself (optional ANY reads)
+ class function GetEncodableIdentity(const AElement: IAsn1Encodable): IAsn1Encodable; static;
+
// Explicit base object methods
class function GetExplicitBaseObject(const ATaggedObject: IAsn1TaggedObject;
ATagClass: Int32): IAsn1Encodable; overload; static;
@@ -201,28 +219,35 @@ TAsn1Utilities = class sealed(TObject)
class function TryParseExplicitContextBaseObject(const ATaggedObjectParser: IAsn1TaggedObjectParser;
ATagNo: Int32; out ABaseObject: IAsn1Convertible): Boolean; overload; static;
- // Sequence cursor methods
- class function ReadContextTagged(const ASequence: IAsn1Sequence;
- var ASequencePosition: Int32; ATagNo: Int32; const AState: TState;
- const AConstructor: TCryptoLibFunc): TResult; static;
- class function ReadTagged(const ASequence: IAsn1Sequence;
- var ASequencePosition: Int32; ATagClass, ATagNo: Int32; const AState: TState;
- const AConstructor: TCryptoLibFunc): TResult; static;
- class function ReadOptional(const ASequence: IAsn1Sequence;
- var ASequencePosition: Int32;
- const AConstructor: TCryptoLibFunc): TResult; static;
- class function ReadOptionalContextTagged(const ASequence: IAsn1Sequence;
- var ASequencePosition: Int32; ATagNo: Int32; const AState: TState;
- const AConstructor: TCryptoLibFunc): TResult; static;
- class function ReadOptionalTagged(const ASequence: IAsn1Sequence;
- var ASequencePosition: Int32; ATagClass, ATagNo: Int32; const AState: TState;
- const AConstructor: TCryptoLibFunc): TResult; static;
- class function TryReadOptionalContextTagged(const ASequence: IAsn1Sequence;
- var ASequencePosition: Int32; ATagNo: Int32; const AState: TState; out AResult: TResult;
- const AConstructor: TCryptoLibFunc): Boolean; static;
- class function TryReadOptionalTagged(const ASequence: IAsn1Sequence;
- var ASequencePosition: Int32; ATagClass, ATagNo: Int32; const AState: TState; out AResult: TResult;
- const AConstructor: TCryptoLibFunc): Boolean; static;
+ // Sequence cursor methods (sequence + position)
+ class procedure CheckSequenceSize(const ASequence: IAsn1Sequence;
+ AMinCount, AMaxCount: Int32); static;
+ class procedure RequireEndOfSequence(const ASequence: IAsn1Sequence;
+ ASequencePosition: Int32); static;
+ class function ReadEncodable(const ASequence: IAsn1Sequence;
+ var ASequencePosition: Int32): IAsn1Encodable; static;
+ class function Read(const ASequence: IAsn1Sequence; var ASequencePosition: Int32;
+ const AConstructor: TAsn1Constructor): TResult; static;
+ class function ReadOptional(const ASequence: IAsn1Sequence; var ASequencePosition: Int32;
+ const AConstructor: TAsn1Constructor): TResult; static;
+ class function ReadTagged(const ASequence: IAsn1Sequence;
+ var ASequencePosition: Int32; ATagClass, ATagNo: Int32; ADeclaredExplicit: Boolean;
+ const AConstructor: TAsn1TaggedConstructor): TResult; static;
+ class function ReadContextTagged(const ASequence: IAsn1Sequence;
+ var ASequencePosition: Int32; ATagNo: Int32; ADeclaredExplicit: Boolean;
+ const AConstructor: TAsn1TaggedConstructor): TResult; static;
+ class function ReadOptionalContextTagged(const ASequence: IAsn1Sequence;
+ var ASequencePosition: Int32; ATagNo: Int32; ADeclaredExplicit: Boolean;
+ const AConstructor: TAsn1TaggedConstructor): TResult; static;
+ class function ReadOptionalTagged(const ASequence: IAsn1Sequence;
+ var ASequencePosition: Int32; ATagClass, ATagNo: Int32; ADeclaredExplicit: Boolean;
+ const AConstructor: TAsn1TaggedConstructor): TResult; static;
+ class function TryReadOptionalContextTagged(const ASequence: IAsn1Sequence;
+ var ASequencePosition: Int32; ATagNo: Int32; ADeclaredExplicit: Boolean; out AResult: TResult;
+ const AConstructor: TAsn1TaggedConstructor): Boolean; static;
+ class function TryReadOptionalTagged(const ASequence: IAsn1Sequence;
+ var ASequencePosition: Int32; ATagClass, ATagNo: Int32; ADeclaredExplicit: Boolean; out AResult: TResult;
+ const AConstructor: TAsn1TaggedConstructor): Boolean; static;
end;
implementation
@@ -489,6 +514,23 @@ class function TAsn1Utilities.GetTaggedChoice(const ATaggedObject: IAsn
Result := AConstructor(ATaggedObject.GetExplicitBaseObject());
end;
+class function TAsn1Utilities.GetTaggedExplicitBaseObject(const ATaggedObject: IAsn1TaggedObject;
+ ADeclaredExplicit: Boolean): IAsn1Encodable;
+begin
+ Result := ATaggedObject.GetExplicitBaseObject();
+end;
+
+class function TAsn1Utilities.GetTaggedObjectIdentity(const ATaggedObject: IAsn1TaggedObject;
+ ADeclaredExplicit: Boolean): IAsn1TaggedObject;
+begin
+ Result := ATaggedObject;
+end;
+
+class function TAsn1Utilities.GetEncodableIdentity(const AElement: IAsn1Encodable): IAsn1Encodable;
+begin
+ Result := AElement;
+end;
+
// Explicit base object methods
class function TAsn1Utilities.GetExplicitBaseObject(const ATaggedObject: IAsn1TaggedObject;
@@ -865,46 +907,48 @@ class function TAsn1Utilities.TryParseExplicitContextBaseObject(const ATaggedObj
// Sequence cursor methods
-class function TAsn1Utilities.ReadContextTagged(const ASequence: IAsn1Sequence;
- var ASequencePosition: Int32; ATagNo: Int32; const AState: TState;
- const AConstructor: TCryptoLibFunc): TResult;
+class procedure TAsn1Utilities.CheckSequenceSize(const ASequence: IAsn1Sequence;
+ AMinCount, AMaxCount: Int32);
begin
- Result := ReadTagged(ASequence, ASequencePosition, TAsn1Tags.ContextSpecific, ATagNo, AState, AConstructor);
+ if ASequence = nil then
+ raise EArgumentNilCryptoLibException.CreateRes(@SSequenceNil);
+ if (ASequence.Count < AMinCount) or (ASequence.Count > AMaxCount) then
+ raise EArgumentCryptoLibException.CreateResFmt(@SBadSequenceSize, [ASequence.Count]);
end;
-class function TAsn1Utilities.ReadTagged(const ASequence: IAsn1Sequence;
- var ASequencePosition: Int32; ATagClass, ATagNo: Int32; const AState: TState;
- const AConstructor: TCryptoLibFunc): TResult;
-var
- LTagged: IAsn1TaggedObject;
- LElement: IAsn1Encodable;
- LObj: IAsn1Object;
+class procedure TAsn1Utilities.RequireEndOfSequence(const ASequence: IAsn1Sequence;
+ ASequencePosition: Int32);
begin
- // TODO: We might want to check the position and throw a better exception, but current ASN.1 types aren't
- // doing that, so leave it until it can be consistent.
- LElement := ASequence.Items[ASequencePosition];
+ if ASequencePosition <> ASequence.Count then
+ raise EArgumentCryptoLibException.CreateRes(@SUnexpectedElementsInSequence);
+end;
+
+class function TAsn1Utilities.ReadEncodable(const ASequence: IAsn1Sequence;
+ var ASequencePosition: Int32): IAsn1Encodable;
+begin
+ if ASequencePosition < 0 then
+ raise EArgumentOutOfRangeCryptoLibException.CreateRes(@SPrematureEndOfSequence);
+ if ASequencePosition >= ASequence.Count then
+ raise EArgumentCryptoLibException.CreateRes(@SPrematureEndOfSequence);
+ Result := ASequence.Items[ASequencePosition];
System.Inc(ASequencePosition);
- if LElement = nil then
- raise EArgumentNilCryptoLibException.CreateRes(@SElementNil);
- LObj := LElement.ToAsn1Object();
- LTagged := TAsn1TaggedObject.GetInstance(LObj, ATagClass, ATagNo);
- Result := AConstructor(LTagged, AState);
end;
-class function TAsn1Utilities.ReadOptional(const ASequence: IAsn1Sequence;
- var ASequencePosition: Int32;
- const AConstructor: TCryptoLibFunc): TResult;
+class function TAsn1Utilities.Read(const ASequence: IAsn1Sequence; var ASequencePosition: Int32;
+ const AConstructor: TAsn1Constructor): TResult;
+begin
+ Result := AConstructor(ReadEncodable(ASequence, ASequencePosition));
+end;
+
+class function TAsn1Utilities.ReadOptional(const ASequence: IAsn1Sequence; var ASequencePosition: Int32;
+ const AConstructor: TAsn1Constructor): TResult;
var
LResult: TResult;
- LResultPtr: Pointer;
begin
if ASequencePosition < ASequence.Count then
begin
LResult := AConstructor(ASequence.Items[ASequencePosition]);
- // Check if result is not nil (for reference types)
- // Since we know TResult will always be a reference type, we check the pointer value
- LResultPtr := PPointer(@LResult)^;
- if LResultPtr <> nil then
+ if PPointer(@LResult)^ <> nil then
begin
System.Inc(ASequencePosition);
Result := LResult;
@@ -914,49 +958,72 @@ class function TAsn1Utilities.ReadOptional(const ASequence: IAsn1Sequen
Result := Default(TResult);
end;
-class function TAsn1Utilities.ReadOptionalContextTagged(const ASequence: IAsn1Sequence;
- var ASequencePosition: Int32; ATagNo: Int32; const AState: TState;
- const AConstructor: TCryptoLibFunc): TResult;
+class function TAsn1Utilities.ReadTagged(const ASequence: IAsn1Sequence;
+ var ASequencePosition: Int32; ATagClass, ATagNo: Int32; ADeclaredExplicit: Boolean;
+ const AConstructor: TAsn1TaggedConstructor): TResult;
+var
+ LTagged: IAsn1TaggedObject;
begin
- Result := ReadOptionalTagged(ASequence, ASequencePosition, TAsn1Tags.ContextSpecific, ATagNo, AState, AConstructor);
+ LTagged := TAsn1TaggedObject.GetInstance(ReadEncodable(ASequence, ASequencePosition).ToAsn1Object(),
+ ATagClass, ATagNo);
+ Result := AConstructor(LTagged, ADeclaredExplicit);
end;
-class function TAsn1Utilities.ReadOptionalTagged(const ASequence: IAsn1Sequence;
- var ASequencePosition: Int32; ATagClass, ATagNo: Int32; const AState: TState;
- const AConstructor: TCryptoLibFunc): TResult;
+class function TAsn1Utilities.ReadContextTagged(const ASequence: IAsn1Sequence;
+ var ASequencePosition: Int32; ATagNo: Int32; ADeclaredExplicit: Boolean;
+ const AConstructor: TAsn1TaggedConstructor): TResult;
+begin
+ Result := ReadTagged(ASequence, ASequencePosition, TAsn1Tags.ContextSpecific, ATagNo,
+ ADeclaredExplicit, AConstructor);
+end;
+
+class function TAsn1Utilities.TryReadOptionalTagged(const ASequence: IAsn1Sequence;
+ var ASequencePosition: Int32; ATagClass, ATagNo: Int32; ADeclaredExplicit: Boolean; out AResult: TResult;
+ const AConstructor: TAsn1TaggedConstructor): Boolean;
var
- LResult: TResult;
+ LTagged: IAsn1TaggedObject;
begin
- if (ASequencePosition < ASequence.Count) and
- (TryGetOptionalTagged(ASequence.Items[ASequencePosition], ATagClass, ATagNo, AState, LResult, AConstructor)) then
+ if ASequencePosition < ASequence.Count then
begin
- System.Inc(ASequencePosition);
- Result := LResult;
- Exit;
+ LTagged := TAsn1TaggedObject.GetOptional(ASequence.Items[ASequencePosition], ATagClass, ATagNo);
+ if LTagged <> nil then
+ begin
+ AResult := AConstructor(LTagged, ADeclaredExplicit);
+ System.Inc(ASequencePosition);
+ Result := True;
+ Exit;
+ end;
end;
- Result := Default(TResult);
+ AResult := Default(TResult);
+ Result := False;
end;
-class function TAsn1Utilities.TryReadOptionalContextTagged(const ASequence: IAsn1Sequence;
- var ASequencePosition: Int32; ATagNo: Int32; const AState: TState; out AResult: TResult;
- const AConstructor: TCryptoLibFunc): Boolean;
+class function TAsn1Utilities.TryReadOptionalContextTagged(const ASequence: IAsn1Sequence;
+ var ASequencePosition: Int32; ATagNo: Int32; ADeclaredExplicit: Boolean; out AResult: TResult;
+ const AConstructor: TAsn1TaggedConstructor): Boolean;
begin
- Result := TryReadOptionalTagged(ASequence, ASequencePosition, TAsn1Tags.ContextSpecific, ATagNo, AState, AResult, AConstructor);
+ Result := TryReadOptionalTagged(ASequence, ASequencePosition, TAsn1Tags.ContextSpecific,
+ ATagNo, ADeclaredExplicit, AResult, AConstructor);
end;
-class function TAsn1Utilities.TryReadOptionalTagged(const ASequence: IAsn1Sequence;
- var ASequencePosition: Int32; ATagClass, ATagNo: Int32; const AState: TState; out AResult: TResult;
- const AConstructor: TCryptoLibFunc): Boolean;
+class function TAsn1Utilities.ReadOptionalTagged(const ASequence: IAsn1Sequence;
+ var ASequencePosition: Int32; ATagClass, ATagNo: Int32; ADeclaredExplicit: Boolean;
+ const AConstructor: TAsn1TaggedConstructor): TResult;
+var
+ LFound: Boolean;
begin
- if (ASequencePosition < ASequence.Count) and
- (TryGetOptionalTagged(ASequence.Items[ASequencePosition], ATagClass, ATagNo, AState, AResult, AConstructor)) then
- begin
- System.Inc(ASequencePosition);
- Result := True;
- Exit;
- end;
- AResult := Default(TResult);
- Result := False;
+ LFound := TryReadOptionalTagged(ASequence, ASequencePosition, ATagClass, ATagNo, ADeclaredExplicit,
+ Result, AConstructor);
+ if not LFound then
+ Result := Default(TResult);
+end;
+
+class function TAsn1Utilities.ReadOptionalContextTagged(const ASequence: IAsn1Sequence;
+ var ASequencePosition: Int32; ATagNo: Int32; ADeclaredExplicit: Boolean;
+ const AConstructor: TAsn1TaggedConstructor): TResult;
+begin
+ Result := ReadOptionalTagged(ASequence, ASequencePosition, TAsn1Tags.ContextSpecific,
+ ATagNo, ADeclaredExplicit, AConstructor);
end;
end.
diff --git a/CryptoLib/src/Asn1/Cms/ClpCmsAsn1Objects.pas b/CryptoLib/src/Asn1/Cms/ClpCmsAsn1Objects.pas
index 24a5828c..51a14377 100644
--- a/CryptoLib/src/Asn1/Cms/ClpCmsAsn1Objects.pas
+++ b/CryptoLib/src/Asn1/Cms/ClpCmsAsn1Objects.pas
@@ -37,8 +37,6 @@ interface
ClpCryptoLibTypes;
resourcestring
- SCmsBadSequenceSize = 'bad sequence size: %d';
- SCmsUnexpectedElementsInSequence = 'unexpected elements in sequence';
SCmsContentTypeNil = 'CMS content type cannot be nil';
SCmsAsn1ElementNil = 'ASN.1 encodable element cannot be nil';
SCmsIssuerNil = 'CMS issuer name cannot be nil';
@@ -118,6 +116,7 @@ TCmsContentInfo = class(TAsn1Encodable, ICmsContentInfo)
class function GetInstance(const AEncoded: TCryptoLibByteArray): ICmsContentInfo; overload; static;
class function GetInstance(const AObj: IAsn1TaggedObject;
AExplicitly: Boolean): ICmsContentInfo; overload; static;
+ class function GetOptional(const AElement: IAsn1Encodable): ICmsContentInfo; static;
class function GetTagged(const ATaggedObject: IAsn1TaggedObject;
ADeclaredExplicit: Boolean): ICmsContentInfo; static;
@@ -144,7 +143,6 @@ TCcmParameters = class(TAsn1Encodable, ICcmParameters)
FNonce: IAsn1OctetString;
FIcvLen: Int32;
- class function ReadOptionalDerInteger(AEnc: IAsn1Encodable): IDerInteger; static;
class function ValidateIcvLen(AIcvLen: Int32): Int32; static;
strict protected
@@ -181,7 +179,6 @@ TGcmParameters = class(TAsn1Encodable, IGcmParameters)
FNonce: IAsn1OctetString;
FIcvLen: Int32;
- class function ReadOptionalDerInteger(AEnc: IAsn1Encodable): IDerInteger; static;
class function ValidateIcvLen(AIcvLen: Int32): Int32; static;
strict protected
@@ -285,8 +282,6 @@ TCmsSignerInfo = class(TAsn1Encodable, ICmsSignerInfo)
FSignature: IAsn1OctetString;
FUnsignedAttrs: IAsn1Set;
- class function GetTaggedAsn1Set(ATagged: IAsn1TaggedObject; AState: Boolean): IAsn1Set; static;
-
strict protected
function GetVersion: IDerInteger;
function GetSignerID: ICmsSignerIdentifier;
@@ -339,8 +334,8 @@ TCmsSignedData = class(TAsn1Encodable, ICmsSignedData)
FSigsBer: Boolean;
strict private
- class function ReadOptionalTaggedSet(const ASequence: IAsn1Sequence;
- var ASequencePosition: Int32; ATagNo: Int32; out AIsBer: Boolean): IAsn1Set; static;
+ class procedure ReadOptionalTaggedSet(const ASeq: IAsn1Sequence; var APos: Int32;
+ ATagNo: Int32; out ASet: IAsn1Set; out AIsBer: Boolean); static;
class function CalculateVersionField(const AContentOid: IDerObjectIdentifier;
const ACerts, ACrls, ASignerInfs: IAsn1Set): IDerInteger; static;
class function HasV3SignerInfos(const ASignerInfs: IAsn1Set): Boolean; static;
@@ -565,26 +560,34 @@ function TCmsContentInfo.IsDLContent(const AContent: IAsn1Encodable): Boolean;
Result := IsDLOctetString(LObj) or IsDLSequenceObj(LObj);
end;
-constructor TCmsContentInfo.Create(const ASeq: IAsn1Sequence);
+class function TCmsContentInfo.GetOptional(const AElement: IAsn1Encodable): ICmsContentInfo;
var
- LCount: Int32;
- LTagged: IAsn1TaggedObject;
+ LSeq: IAsn1Sequence;
begin
- Inherited Create();
- LCount := ASeq.Count;
- if (LCount < 1) or (LCount > 2) then
- raise EArgumentCryptoLibException.CreateResFmt(@SCmsBadSequenceSize, [LCount]);
-
- FContentType := TDerObjectIdentifier.GetInstance(ASeq[0]);
-
- if ASeq.Count > 1 then
+ if AElement = nil then
+ raise EArgumentNilCryptoLibException.CreateRes(@SCmsAsn1ElementNil);
+ if Supports(AElement, ICmsContentInfo, Result) then
+ Exit;
+ LSeq := TAsn1Sequence.GetOptional(AElement);
+ if LSeq <> nil then
begin
- LTagged := TAsn1TaggedObject.GetContextInstance(ASeq[1], 0);
- FContent := LTagged.GetExplicitBaseObject();
- end
- else
- FContent := nil;
+ Result := TCmsContentInfo.Create(LSeq);
+ Exit;
+ end;
+ Result := nil;
+end;
+constructor TCmsContentInfo.Create(const ASeq: IAsn1Sequence);
+var
+ LPos: Int32;
+begin
+ Inherited Create();
+ LPos := 0;
+ TAsn1Utilities.CheckSequenceSize(ASeq, 1, 2);
+ FContentType := TAsn1Utilities.Read(ASeq, LPos, TDerObjectIdentifier.GetInstance);
+ FContent := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 0, True,
+ TAsn1Utilities.GetTaggedExplicitBaseObject);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
FIsDefiniteLength := IsDLSequence(ASeq);
end;
@@ -689,14 +692,14 @@ class function TCmsIssuerAndSerialNumber.GetTagged(const ATaggedObject: IAsn1Tag
constructor TCmsIssuerAndSerialNumber.Create(const ASeq: IAsn1Sequence);
var
- LCount: Int32;
+ LPos: Int32;
begin
Inherited Create();
- LCount := ASeq.Count;
- if LCount <> 2 then
- raise EArgumentCryptoLibException.CreateResFmt(@SCmsBadSequenceSize, [LCount]);
- FIssuer := TX509Name.GetInstance(ASeq[0]);
- FSerialNumber := TDerInteger.GetInstance(ASeq[1]);
+ LPos := 0;
+ TAsn1Utilities.CheckSequenceSize(ASeq, 2, 2);
+ FIssuer := TAsn1Utilities.Read(ASeq, LPos, TX509Name.GetInstance);
+ FSerialNumber := TAsn1Utilities.Read(ASeq, LPos, TDerInteger.GetInstance);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
constructor TCmsIssuerAndSerialNumber.Create(const AIssuer: IX509Name; const ASerialNumber: IDerInteger);
@@ -873,34 +876,19 @@ class function TCmsSignerInfo.GetTagged(const ATaggedObject: IAsn1TaggedObject;
constructor TCmsSignerInfo.Create(const ASeq: IAsn1Sequence);
var
- LCount, LPos: Int32;
+ LPos: Int32;
begin
Inherited Create();
- LCount := ASeq.Count;
- if (LCount < 5) or (LCount > 7) then
- raise EArgumentCryptoLibException.CreateResFmt(@SCmsBadSequenceSize, [LCount]);
LPos := 0;
- FVersion := TDerInteger.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
- FSignerID := TCmsSignerIdentifier.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
- FDigestAlgorithm := TAlgorithmIdentifier.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
- FSignedAttrs := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 0, False,
- GetTaggedAsn1Set);
- FSignatureAlgorithm := TAlgorithmIdentifier.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
- FSignature := TAsn1OctetString.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
- FUnsignedAttrs := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 1, False,
- GetTaggedAsn1Set);
- if LPos <> LCount then
- raise EArgumentCryptoLibException.CreateRes(@SCmsUnexpectedElementsInSequence);
-end;
-
-class function TCmsSignerInfo.GetTaggedAsn1Set(ATagged: IAsn1TaggedObject; AState: Boolean): IAsn1Set;
-begin
- Result := TAsn1Set.GetTagged(ATagged, AState);
+ TAsn1Utilities.CheckSequenceSize(ASeq, 5, 7);
+ FVersion := TAsn1Utilities.Read(ASeq, LPos, TDerInteger.GetInstance);
+ FSignerID := TAsn1Utilities.Read(ASeq, LPos, TCmsSignerIdentifier.GetInstance);
+ FDigestAlgorithm := TAsn1Utilities.Read(ASeq, LPos, TAlgorithmIdentifier.GetInstance);
+ FSignedAttrs := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 0, False, TAsn1Set.GetTagged);
+ FSignatureAlgorithm := TAsn1Utilities.Read(ASeq, LPos, TAlgorithmIdentifier.GetInstance);
+ FSignature := TAsn1Utilities.Read(ASeq, LPos, TAsn1OctetString.GetInstance);
+ FUnsignedAttrs := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 1, False, TAsn1Set.GetTagged);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
constructor TCmsSignerInfo.Create(const ASignerID: ICmsSignerIdentifier;
@@ -979,24 +967,24 @@ function TCmsSignerInfo.ToAsn1Object: IAsn1Object;
{ TCmsSignedData }
-class function TCmsSignedData.ReadOptionalTaggedSet(const ASequence: IAsn1Sequence;
- var ASequencePosition: Int32; ATagNo: Int32; out AIsBer: Boolean): IAsn1Set;
+class procedure TCmsSignedData.ReadOptionalTaggedSet(const ASeq: IAsn1Sequence; var APos: Int32;
+ ATagNo: Int32; out ASet: IAsn1Set; out AIsBer: Boolean);
var
- LElement: IAsn1Encodable;
LTagged: IAsn1TaggedObject;
+ LFound: Boolean;
begin
- Result := nil;
- AIsBer := False;
- if ASequencePosition >= ASequence.Count then
- Exit;
- LElement := ASequence.Items[ASequencePosition];
- if not Supports(LElement, IAsn1TaggedObject, LTagged) then
- Exit;
- if not LTagged.HasContextTag(ATagNo) then
- Exit;
- Result := TAsn1Set.GetTagged(LTagged, False);
- AIsBer := Supports(LElement, IBerTaggedObject);
- System.Inc(ASequencePosition);
+ LFound := TAsn1Utilities.TryReadOptionalContextTagged(ASeq, APos, ATagNo, False,
+ LTagged, TAsn1Utilities.GetTaggedObjectIdentity);
+ if LFound then
+ begin
+ ASet := TAsn1Set.GetTagged(LTagged, False);
+ AIsBer := Supports(LTagged, IBerTaggedObject);
+ end
+ else
+ begin
+ ASet := nil;
+ AIsBer := False;
+ end;
end;
class function TCmsSignedData.CalculateVersionField(const AContentOid: IDerObjectIdentifier;
@@ -1162,27 +1150,18 @@ class function TCmsSignedData.FromContentInfo(const AInfo: ICmsContentInfo): ICm
constructor TCmsSignedData.Create(const ASeq: IAsn1Sequence);
var
- LCount, LPos: Int32;
+ LPos: Int32;
begin
Inherited Create();
- LCount := ASeq.Count;
- if (LCount < 4) or (LCount > 6) then
- raise EArgumentCryptoLibException.CreateResFmt(@SCmsBadSequenceSize, [LCount]);
-
LPos := 0;
- FVersion := TDerInteger.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
- FDigestAlgorithms := TAsn1Set.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
- FEncapContentInfo := TCmsContentInfo.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
- FCertificates := ReadOptionalTaggedSet(ASeq, LPos, 0, FCertsBer);
- FCrls := ReadOptionalTaggedSet(ASeq, LPos, 1, FCrlsBer);
- FSignerInfos := TAsn1Set.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
-
- if LPos <> LCount then
- raise EArgumentCryptoLibException.CreateRes(@SCmsUnexpectedElementsInSequence);
+ TAsn1Utilities.CheckSequenceSize(ASeq, 4, 6);
+ FVersion := TAsn1Utilities.Read(ASeq, LPos, TDerInteger.GetInstance);
+ FDigestAlgorithms := TAsn1Utilities.Read(ASeq, LPos, TAsn1Set.GetInstance);
+ FEncapContentInfo := TAsn1Utilities.Read(ASeq, LPos, TCmsContentInfo.GetInstance);
+ ReadOptionalTaggedSet(ASeq, LPos, 0, FCertificates, FCertsBer);
+ ReadOptionalTaggedSet(ASeq, LPos, 1, FCrls, FCrlsBer);
+ FSignerInfos := TAsn1Utilities.Read(ASeq, LPos, TAsn1Set.GetInstance);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
FDigsBer := Supports(FDigestAlgorithms, IBerSet);
FSigsBer := Supports(FSignerInfos, IBerSet);
@@ -1276,11 +1255,6 @@ function TCmsSignedData.ToAsn1Object: IAsn1Object;
{ TCcmParameters }
-class function TCcmParameters.ReadOptionalDerInteger(AEnc: IAsn1Encodable): IDerInteger;
-begin
- Result := TDerInteger.GetOptional(AEnc);
-end;
-
class function TCcmParameters.ValidateIcvLen(AIcvLen: Int32): Int32;
begin
if (AIcvLen < 4) or (AIcvLen > 16) or ((AIcvLen and 1) <> 0) then
@@ -1326,20 +1300,15 @@ class function TCcmParameters.GetTagged(const ATaggedObject: IAsn1TaggedObject;
constructor TCcmParameters.Create(const ASeq: IAsn1Sequence);
var
- LCount, LPos: Int32;
+ LPos: Int32;
LIcvLen: IDerInteger;
begin
inherited Create();
- LCount := ASeq.Count;
LPos := 0;
- if (LCount < 1) or (LCount > 2) then
- raise EArgumentCryptoLibException.CreateResFmt(@SCmsBadSequenceSize, [LCount]);
-
- FNonce := TAsn1OctetString.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
- LIcvLen := TAsn1Utilities.ReadOptional(ASeq, LPos, ReadOptionalDerInteger);
- if LPos <> LCount then
- raise EArgumentCryptoLibException.CreateRes(@SCmsUnexpectedElementsInSequence);
+ TAsn1Utilities.CheckSequenceSize(ASeq, 1, 2);
+ FNonce := TAsn1Utilities.Read(ASeq, LPos, TAsn1OctetString.GetInstance);
+ LIcvLen := TAsn1Utilities.ReadOptional(ASeq, LPos, TDerInteger.GetOptional);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
if LIcvLen = nil then
FIcvLen := ValidateIcvLen(DefaultIcvLen)
@@ -1375,11 +1344,6 @@ function TCcmParameters.ToAsn1Object: IAsn1Object;
{ TGcmParameters }
-class function TGcmParameters.ReadOptionalDerInteger(AEnc: IAsn1Encodable): IDerInteger;
-begin
- Result := TDerInteger.GetOptional(AEnc);
-end;
-
class function TGcmParameters.ValidateIcvLen(AIcvLen: Int32): Int32;
begin
if (AIcvLen < 12) or (AIcvLen > 16) then
@@ -1425,20 +1389,15 @@ class function TGcmParameters.GetTagged(const ATaggedObject: IAsn1TaggedObject;
constructor TGcmParameters.Create(const ASeq: IAsn1Sequence);
var
- LCount, LPos: Int32;
+ LPos: Int32;
LIcvLen: IDerInteger;
begin
inherited Create();
- LCount := ASeq.Count;
LPos := 0;
- if (LCount < 1) or (LCount > 2) then
- raise EArgumentCryptoLibException.CreateResFmt(@SCmsBadSequenceSize, [LCount]);
-
- FNonce := TAsn1OctetString.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
- LIcvLen := TAsn1Utilities.ReadOptional(ASeq, LPos, ReadOptionalDerInteger);
- if LPos <> LCount then
- raise EArgumentCryptoLibException.CreateRes(@SCmsUnexpectedElementsInSequence);
+ TAsn1Utilities.CheckSequenceSize(ASeq, 1, 2);
+ FNonce := TAsn1Utilities.Read(ASeq, LPos, TAsn1OctetString.GetInstance);
+ LIcvLen := TAsn1Utilities.ReadOptional(ASeq, LPos, TDerInteger.GetOptional);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
if LIcvLen = nil then
FIcvLen := ValidateIcvLen(DefaultIcvLen)
diff --git a/CryptoLib/src/Asn1/Cms/ClpCmsECAsn1Objects.pas b/CryptoLib/src/Asn1/Cms/ClpCmsECAsn1Objects.pas
index 232a79a6..74f7e006 100644
--- a/CryptoLib/src/Asn1/Cms/ClpCmsECAsn1Objects.pas
+++ b/CryptoLib/src/Asn1/Cms/ClpCmsECAsn1Objects.pas
@@ -50,7 +50,6 @@ TEccCmsSharedInfo = class(TAsn1Encodable, IEccCmsSharedInfo)
FEntityUInfo: IAsn1OctetString;
FSuppPubInfo: IAsn1OctetString;
- class function GetTaggedAsn1OctetString(ATagged: IAsn1TaggedObject; AState: Boolean): IAsn1OctetString; static;
strict protected
function GetKeyInfo: IAlgorithmIdentifier;
@@ -129,32 +128,19 @@ class function TEccCmsSharedInfo.GetTagged(const ATaggedObject: IAsn1TaggedObjec
Result := TEccCmsSharedInfo.Create(TAsn1Sequence.GetTagged(ATaggedObject, ADeclaredExplicit));
end;
-class function TEccCmsSharedInfo.GetTaggedAsn1OctetString(ATagged: IAsn1TaggedObject; AState: Boolean): IAsn1OctetString;
-begin
- Result := TAsn1OctetString.GetTagged(ATagged, AState);
-end;
-
constructor TEccCmsSharedInfo.Create(const ASeq: IAsn1Sequence);
var
- LCount, LPos: Int32;
+ LPos: Int32;
begin
inherited Create();
- LCount := ASeq.Count;
LPos := 0;
- if (LCount < 2) or (LCount > 3) then
- raise EArgumentCryptoLibException.CreateResFmt(@SEccCmsBadSequenceSize, [LCount]);
-
- FKeyInfo := TAlgorithmIdentifier.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
-
- FEntityUInfo := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 0, True,
- GetTaggedAsn1OctetString);
-
- FSuppPubInfo := TAsn1Utilities.ReadContextTagged(ASeq, LPos, 2, True,
- GetTaggedAsn1OctetString);
-
- if LPos <> LCount then
- raise EArgumentCryptoLibException.CreateRes(@SEccCmsUnexpectedElementsInSequence);
+ TAsn1Utilities.CheckSequenceSize(ASeq, 2, 3);
+ FKeyInfo := TAsn1Utilities.Read(ASeq, LPos, TAlgorithmIdentifier.GetInstance);
+ FEntityUInfo := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 0, True,
+ TAsn1OctetString.GetTagged);
+ FSuppPubInfo := TAsn1Utilities.ReadContextTagged(ASeq, LPos, 2, True,
+ TAsn1OctetString.GetTagged);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
constructor TEccCmsSharedInfo.Create(const AKeyInfo: IAlgorithmIdentifier; const ASuppPubInfo: IAsn1OctetString);
diff --git a/CryptoLib/src/Asn1/Pkcs/ClpPkcsAsn1Objects.pas b/CryptoLib/src/Asn1/Pkcs/ClpPkcsAsn1Objects.pas
index fac761f4..79bb2f27 100644
--- a/CryptoLib/src/Asn1/Pkcs/ClpPkcsAsn1Objects.pas
+++ b/CryptoLib/src/Asn1/Pkcs/ClpPkcsAsn1Objects.pas
@@ -40,7 +40,6 @@ interface
resourcestring
SAttrTypeNil = 'attribute type cannot be nil';
SAttrValuesNil = 'attribute values cannot be nil';
- SWrongNumberOfElements = 'wrong number of elements in sequence';
SRequestInfoNil = 'request info cannot be nil';
SAlgorithmNil = 'algorithm identifier cannot be nil';
SSignatureNil = 'signature cannot be nil';
@@ -122,8 +121,6 @@ TPkcsSignedData = class(TAsn1Encodable, IPkcsSignedData)
FCrls: IAsn1Set;
FSignerInfos: IAsn1Set;
- class function GetTaggedAsn1SetFromSeq(ATagged: IAsn1TaggedObject; AState: IAsn1Sequence): IAsn1Set; static;
-
strict protected
function GetVersion: IDerInteger;
function GetDigestAlgorithms: IAsn1Set;
@@ -203,8 +200,6 @@ TCertificationRequestInfo = class(TAsn1Encodable, ICertificationRequestInfo)
FSubjectPKInfo: ISubjectPublicKeyInfo;
FAttributes: IAsn1Set;
- class function GetTaggedAsn1Set(ATagged: IAsn1TaggedObject; AState: Boolean): IAsn1Set; static;
-
strict protected
function GetVersion: IDerInteger;
function GetSubject: IX509Name;
@@ -288,9 +283,6 @@ TPrivateKeyInfo = class(TAsn1Encodable, IPrivateKeyInfo)
FAttributes: IAsn1Set;
FPublicKey: IDerBitString;
- class function GetTaggedAsn1Set(ATagged: IAsn1TaggedObject; AState: Boolean): IAsn1Set; static;
- class function GetTaggedDerBitString(ATagged: IAsn1TaggedObject; AState: Boolean): IDerBitString; static;
-
strict protected
function GetVersion: IDerInteger;
function GetPrivateKeyAlgorithm: IAlgorithmIdentifier;
@@ -478,8 +470,6 @@ TPbkdf2Params = class(TAsn1Encodable, IPbkdf2Params)
FDefaultPrf: IAlgorithmIdentifier;
class constructor Create(); overload;
- class function ReadOptionalDerInteger(AEnc: IAsn1Encodable): IDerInteger; static;
- class function ReadOptionalAlgorithmIdentifier(AEnc: IAsn1Encodable): IAlgorithmIdentifier; static;
strict protected
function GetSalt: IAsn1OctetString;
@@ -562,8 +552,6 @@ TMacData = class(TAsn1Encodable, IMacData)
FMacSalt: IAsn1OctetString;
FIterations: IDerInteger;
- class function ReadOptionalDerInteger(AEnc: IAsn1Encodable): IDerInteger; static;
-
strict protected
function GetMac: IDigestInfo;
function GetSalt: TCryptoLibByteArray;
@@ -577,6 +565,7 @@ TMacData = class(TAsn1Encodable, IMacData)
class function GetInstance(const AEncoded: TCryptoLibByteArray): IMacData; overload; static;
class function GetInstance(const AObj: IAsn1TaggedObject;
AExplicitly: Boolean): IMacData; overload; static;
+ class function GetOptional(const AElement: IAsn1Encodable): IMacData; static;
class function GetTagged(const ATaggedObject: IAsn1TaggedObject;
ADeclaredExplicit: Boolean): IMacData; static;
@@ -604,7 +593,6 @@ TSafeBag = class(TAsn1Encodable, ISafeBag)
FBagValue: IAsn1Encodable;
FBagAttributes: IAsn1Set;
- class function ReadOptionalAsn1Set(AElement: IAsn1Encodable): IAsn1Set; static;
strict protected
function GetBagID: IDerObjectIdentifier;
@@ -824,18 +812,14 @@ class function TAttributePkcs.GetTagged(const ATaggedObject: IAsn1TaggedObject;
constructor TAttributePkcs.Create(const ASeq: IAsn1Sequence);
var
- LCount: Int32;
+ LPos: Int32;
begin
inherited Create();
-
- LCount := ASeq.Count;
- if LCount <> 2 then
- begin
- raise EArgumentCryptoLibException.CreateResFmt(@SPkcsBadSequenceSize, [LCount]);
- end;
-
- FAttrType := TDerObjectIdentifier.GetInstance(ASeq[0]);
- FAttrValues := TAsn1Set.GetInstance(ASeq[1]);
+ LPos := 0;
+ TAsn1Utilities.CheckSequenceSize(ASeq, 2, 2);
+ FAttrType := TAsn1Utilities.Read(ASeq, LPos, TDerObjectIdentifier.GetInstance);
+ FAttrValues := TAsn1Utilities.Read(ASeq, LPos, TAsn1Set.GetInstance);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
constructor TAttributePkcs.Create(const AAttrType: IDerObjectIdentifier;
@@ -922,41 +906,21 @@ class function TCertificationRequestInfo.GetTagged(const ATaggedObject: IAsn1Tag
constructor TCertificationRequestInfo.Create(const ASeq: IAsn1Sequence);
var
- LCount, LPos: Int32;
+ LPos: Int32;
begin
inherited Create();
-
- LCount := ASeq.Count;
LPos := 0;
- if (LCount < 3) or (LCount > 4) then
- begin
- raise EArgumentCryptoLibException.CreateResFmt(@SPkcsBadSequenceSize, [LCount]);
- end;
-
- FVersion := TDerInteger.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
- FSubject := TX509Name.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
- FSubjectPKInfo := TSubjectPublicKeyInfo.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
-
+ TAsn1Utilities.CheckSequenceSize(ASeq, 3, 4);
+ FVersion := TAsn1Utilities.Read(ASeq, LPos, TDerInteger.GetInstance);
+ FSubject := TAsn1Utilities.Read(ASeq, LPos, TX509Name.GetInstance);
+ FSubjectPKInfo := TAsn1Utilities.Read(ASeq, LPos, TSubjectPublicKeyInfo.GetInstance);
// NOTE: some CertificationRequestInfo objects seem to treat this field as optional.
- FAttributes := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 0, False,
- GetTaggedAsn1Set);
-
- if LPos <> LCount then
- begin
- raise EArgumentCryptoLibException.CreateRes(@SUnexpectedElementsInSequence);
- end;
-
+ FAttributes := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 0, False,
+ TAsn1Set.GetTagged);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
ValidateAttributes(FAttributes);
end;
-class function TCertificationRequestInfo.GetTaggedAsn1Set(ATagged: IAsn1TaggedObject; AState: Boolean): IAsn1Set;
-begin
- Result := TAsn1Set.GetTagged(ATagged, AState);
-end;
-
constructor TCertificationRequestInfo.Create(const ASubject: IX509Name;
const APkInfo: ISubjectPublicKeyInfo; const AAttributes: IAsn1Set);
begin
@@ -1085,19 +1049,15 @@ constructor TCertificationRequest.Create;
constructor TCertificationRequest.Create(const ASeq: IAsn1Sequence);
var
- LCount: Int32;
+ LPos: Int32;
begin
inherited Create();
-
- LCount := ASeq.Count;
- if LCount <> 3 then
- begin
- raise EArgumentCryptoLibException.CreateRes(@SWrongNumberOfElements);
- end;
-
- FReqInfo := TCertificationRequestInfo.GetInstance(ASeq[0]);
- FSigAlgId := TAlgorithmIdentifier.GetInstance(ASeq[1]);
- FSigBits := TDerBitString.GetInstance(ASeq[2]);
+ LPos := 0;
+ TAsn1Utilities.CheckSequenceSize(ASeq, 3, 3);
+ FReqInfo := TAsn1Utilities.Read(ASeq, LPos, TCertificationRequestInfo.GetInstance);
+ FSigAlgId := TAsn1Utilities.Read(ASeq, LPos, TAlgorithmIdentifier.GetInstance);
+ FSigBits := TAsn1Utilities.Read(ASeq, LPos, TDerBitString.GetInstance);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
constructor TCertificationRequest.Create(const ARequestInfo: ICertificationRequestInfo;
@@ -1214,50 +1174,24 @@ class function TPrivateKeyInfo.GetTagged(const ATaggedObject: IAsn1TaggedObject;
constructor TPrivateKeyInfo.Create(const ASeq: IAsn1Sequence);
var
- LCount, LPos, LVersionValue: Int32;
+ LPos: Int32;
+ LVersionValue: Int32;
begin
inherited Create();
-
- LCount := ASeq.Count;
LPos := 0;
- if (LCount < 3) or (LCount > 5) then
- begin
- raise EArgumentCryptoLibException.CreateResFmt(@SPkcsBadSequenceSize, [LCount]);
- end;
-
- FVersion := TDerInteger.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
- FPrivateKeyAlgorithm := TAlgorithmIdentifier.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
- FPrivateKey := TAsn1OctetString.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
-
- FAttributes := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 0, False,
- GetTaggedAsn1Set);
-
- FPublicKey := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 1, False,
- GetTaggedDerBitString);
-
- if LPos <> LCount then
- begin
- raise EArgumentCryptoLibException.CreateRes(@SUnexpectedElementsInSequence);
- end;
+ TAsn1Utilities.CheckSequenceSize(ASeq, 3, 5);
+ FVersion := TAsn1Utilities.Read(ASeq, LPos, TDerInteger.GetInstance);
+ FPrivateKeyAlgorithm := TAsn1Utilities.Read(ASeq, LPos, TAlgorithmIdentifier.GetInstance);
+ FPrivateKey := TAsn1Utilities.Read(ASeq, LPos, TAsn1OctetString.GetInstance);
+ FAttributes := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 0, False,
+ TAsn1Set.GetTagged);
+ FPublicKey := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 1, False,
+ TDerBitString.GetTagged);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
LVersionValue := FVersion.IntValueExact;
if (FPublicKey <> nil) and (LVersionValue < 1) then
- begin
raise EArgumentCryptoLibException.CreateRes(@SPublicKeyRequiresVersionV21OrLater);
- end;
-end;
-
-class function TPrivateKeyInfo.GetTaggedAsn1Set(ATagged: IAsn1TaggedObject; AState: Boolean): IAsn1Set;
-begin
- Result := TAsn1Set.GetTagged(ATagged, AState);
-end;
-
-class function TPrivateKeyInfo.GetTaggedDerBitString(ATagged: IAsn1TaggedObject; AState: Boolean): IDerBitString;
-begin
- Result := TDerBitString.GetTagged(ATagged, AState);
end;
constructor TPrivateKeyInfo.Create(const APrivateKeyAlgorithm: IAlgorithmIdentifier;
@@ -1414,16 +1348,14 @@ class function TEncryptedPrivateKeyInfo.GetTagged(const ATaggedObject: IAsn1Tagg
constructor TEncryptedPrivateKeyInfo.Create(const ASeq: IAsn1Sequence);
var
- LCount: Int32;
+ LPos: Int32;
begin
inherited Create();
-
- LCount := ASeq.Count;
- if LCount <> 2 then
- raise EArgumentCryptoLibException.CreateResFmt(@SPkcsBadSequenceSize, [LCount]);
-
- FEncryptionAlgorithm := TAlgorithmIdentifier.GetInstance(ASeq[0]);
- FEncryptedData := TAsn1OctetString.GetInstance(ASeq[1]);
+ LPos := 0;
+ TAsn1Utilities.CheckSequenceSize(ASeq, 2, 2);
+ FEncryptionAlgorithm := TAsn1Utilities.Read(ASeq, LPos, TAlgorithmIdentifier.GetInstance);
+ FEncryptedData := TAsn1Utilities.Read(ASeq, LPos, TAsn1OctetString.GetInstance);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
constructor TEncryptedPrivateKeyInfo.Create(const AAlgId: IAlgorithmIdentifier;
@@ -1550,8 +1482,17 @@ constructor TEncryptionScheme.Create(const AObjectID: IDerObjectIdentifier;
end;
constructor TEncryptionScheme.Create(const ASeq: IAsn1Sequence);
+var
+ LPos: Int32;
+ LObjectID: IDerObjectIdentifier;
+ LParameters: IAsn1Encodable;
begin
- Create(TDerObjectIdentifier.GetInstance(ASeq[0]), ASeq[1]);
+ LPos := 0;
+ TAsn1Utilities.CheckSequenceSize(ASeq, 2, 2);
+ LObjectID := TAsn1Utilities.Read(ASeq, LPos, TDerObjectIdentifier.GetInstance);
+ LParameters := TAsn1Utilities.ReadEncodable(ASeq, LPos);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
+ Create(LObjectID, LParameters);
end;
function TEncryptionScheme.GetParametersAsn1Object: IAsn1Object;
@@ -1612,14 +1553,14 @@ class function TPbeParameter.GetTagged(const ATaggedObject: IAsn1TaggedObject;
constructor TPbeParameter.Create(const ASeq: IAsn1Sequence);
var
- LCount: Int32;
+ LPos: Int32;
begin
inherited Create();
- LCount := ASeq.Count;
- if LCount <> 2 then
- raise EArgumentCryptoLibException.CreateResFmt(@SPkcsBadSequenceSize, [LCount]);
- FSalt := TAsn1OctetString.GetInstance(ASeq[0]);
- FIterationCount := TDerInteger.GetInstance(ASeq[1]);
+ LPos := 0;
+ TAsn1Utilities.CheckSequenceSize(ASeq, 2, 2);
+ FSalt := TAsn1Utilities.Read(ASeq, LPos, TAsn1OctetString.GetInstance);
+ FIterationCount := TAsn1Utilities.Read(ASeq, LPos, TDerInteger.GetInstance);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
constructor TPbeParameter.Create(const ASalt: TCryptoLibByteArray; AIterationCount: Int32);
@@ -1699,16 +1640,16 @@ class function TPbeS2Parameters.GetTagged(const ATaggedObject: IAsn1TaggedObject
constructor TPbeS2Parameters.Create(const ASeq: IAsn1Sequence);
var
- LCount: Int32;
+ LPos: Int32;
LFunc: IAlgorithmIdentifier;
begin
inherited Create();
- LCount := ASeq.Count;
- if LCount <> 2 then
- raise EArgumentCryptoLibException.CreateResFmt(@SPkcsBadSequenceSize, [LCount]);
- LFunc := TAlgorithmIdentifier.GetInstance(ASeq[0]);
+ LPos := 0;
+ TAsn1Utilities.CheckSequenceSize(ASeq, 2, 2);
+ LFunc := TAsn1Utilities.Read(ASeq, LPos, TAlgorithmIdentifier.GetInstance);
FKeyDerivationFunc := TKeyDerivationFunc.Create(LFunc.Algorithm, LFunc.Parameters);
- FEncryptionScheme := TEncryptionScheme.GetEncryptionSchemeInstance(ASeq[1]);
+ FEncryptionScheme := TEncryptionScheme.GetEncryptionSchemeInstance(TAsn1Utilities.ReadEncodable(ASeq, LPos));
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
constructor TPbeS2Parameters.Create(const AKeyDerivationFunc: IKeyDerivationFunc;
@@ -1788,33 +1729,18 @@ class function TPbkdf2Params.GetTagged(const ATaggedObject: IAsn1TaggedObject;
constructor TPbkdf2Params.Create(const ASeq: IAsn1Sequence);
var
- LCount, LPos: Int32;
+ LPos: Int32;
begin
inherited Create();
- LCount := ASeq.Count;
LPos := 0;
- if (LCount < 2) or (LCount > 4) then
- raise EArgumentCryptoLibException.CreateResFmt(@SPkcsBadSequenceSize, [LCount]);
- FOctStr := TAsn1OctetString.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
- FIterationCount := TDerInteger.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
- FKeyLength := TAsn1Utilities.ReadOptional(ASeq, LPos, ReadOptionalDerInteger);
- FPrf := TAsn1Utilities.ReadOptional(ASeq, LPos, ReadOptionalAlgorithmIdentifier);
+ TAsn1Utilities.CheckSequenceSize(ASeq, 2, 4);
+ FOctStr := TAsn1Utilities.Read(ASeq, LPos, TAsn1OctetString.GetInstance);
+ FIterationCount := TAsn1Utilities.Read(ASeq, LPos, TDerInteger.GetInstance);
+ FKeyLength := TAsn1Utilities.ReadOptional(ASeq, LPos, TDerInteger.GetOptional);
+ FPrf := TAsn1Utilities.ReadOptional(ASeq, LPos, TAlgorithmIdentifier.GetOptional);
if FPrf = nil then
FPrf := DefaultPrf;
- if LPos <> LCount then
- raise EArgumentCryptoLibException.CreateRes(@SUnexpectedElementsInSequence);
-end;
-
-class function TPbkdf2Params.ReadOptionalDerInteger(AEnc: IAsn1Encodable): IDerInteger;
-begin
- Result := TDerInteger.GetOptional(AEnc);
-end;
-
-class function TPbkdf2Params.ReadOptionalAlgorithmIdentifier(AEnc: IAsn1Encodable): IAlgorithmIdentifier;
-begin
- Result := TAlgorithmIdentifier.GetOptional(AEnc);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
constructor TPbkdf2Params.Create(const ASalt: TCryptoLibByteArray; AIterationCount: Int32);
@@ -1959,14 +1885,14 @@ class function TPkcs12PbeParams.GetTagged(const ATaggedObject: IAsn1TaggedObject
constructor TPkcs12PbeParams.Create(const ASeq: IAsn1Sequence);
var
- LCount: Int32;
+ LPos: Int32;
begin
inherited Create();
- LCount := ASeq.Count;
- if LCount <> 2 then
- raise EArgumentCryptoLibException.CreateResFmt(@SPkcsBadSequenceSize, [LCount]);
- FIV := TAsn1OctetString.GetInstance(ASeq[0]);
- FIterations := TDerInteger.GetInstance(ASeq[1]);
+ LPos := 0;
+ TAsn1Utilities.CheckSequenceSize(ASeq, 2, 2);
+ FIV := TAsn1Utilities.Read(ASeq, LPos, TAsn1OctetString.GetInstance);
+ FIterations := TAsn1Utilities.Read(ASeq, LPos, TDerInteger.GetInstance);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
constructor TPkcs12PbeParams.Create(const ASalt: TCryptoLibByteArray; AIterations: Int32);
@@ -2056,25 +1982,15 @@ class function TPkcsContentInfo.GetTagged(const ATaggedObject: IAsn1TaggedObject
constructor TPkcsContentInfo.Create(const ASeq: IAsn1Sequence);
var
- LCount: Int32;
- LTagged: IAsn1TaggedObject;
+ LPos: Int32;
begin
Inherited Create();
- LCount := ASeq.Count;
- if (LCount < 1) or (LCount > 2) then
- raise EArgumentCryptoLibException.CreateResFmt(@SPkcsBadSequenceSize, [LCount]);
-
- FContentType := TDerObjectIdentifier.GetInstance(ASeq[0]);
-
- if ASeq.Count > 1 then
- begin
- LTagged := TAsn1TaggedObject.GetContextInstance(ASeq[1], 0);
- FContent := LTagged.GetExplicitBaseObject();
- end
- else
- begin
- FContent := nil;
- end;
+ LPos := 0;
+ TAsn1Utilities.CheckSequenceSize(ASeq, 1, 2);
+ FContentType := TAsn1Utilities.Read(ASeq, LPos, TDerObjectIdentifier.GetInstance);
+ FContent := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 0, True,
+ TAsn1Utilities.GetTaggedExplicitBaseObject);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
constructor TPkcsContentInfo.Create(const AContentType: IDerObjectIdentifier;
@@ -2165,36 +2081,20 @@ class function TPkcsSignedData.GetTagged(const ATaggedObject: IAsn1TaggedObject;
constructor TPkcsSignedData.Create(const ASeq: IAsn1Sequence);
var
- LCount, LPos: Int32;
+ LPos: Int32;
begin
Inherited Create();
- LCount := ASeq.Count;
LPos := 0;
- if (LCount < 4) or (LCount > 6) then
- raise EArgumentCryptoLibException.CreateResFmt(@SPkcsBadSequenceSize, [LCount]);
-
- FVersion := TDerInteger.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
- FDigestAlgorithms := TAsn1Set.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
- FContentInfo := TPkcsContentInfo.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
- FCertificates := TAsn1Utilities.ReadOptionalContextTagged(
- ASeq, LPos, 0, ASeq,
- GetTaggedAsn1SetFromSeq);
- FCrls := TAsn1Utilities.ReadOptionalContextTagged(
- ASeq, LPos, 1, ASeq,
- GetTaggedAsn1SetFromSeq);
- FSignerInfos := TAsn1Set.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
-
- if LPos <> LCount then
- raise EArgumentCryptoLibException.CreateRes(@SUnexpectedElementsInSequence);
-end;
-
-class function TPkcsSignedData.GetTaggedAsn1SetFromSeq(ATagged: IAsn1TaggedObject; AState: IAsn1Sequence): IAsn1Set;
-begin
- Result := TAsn1Set.GetTagged(ATagged, False);
+ TAsn1Utilities.CheckSequenceSize(ASeq, 4, 6);
+ FVersion := TAsn1Utilities.Read(ASeq, LPos, TDerInteger.GetInstance);
+ FDigestAlgorithms := TAsn1Utilities.Read(ASeq, LPos, TAsn1Set.GetInstance);
+ FContentInfo := TAsn1Utilities.Read(ASeq, LPos, TPkcsContentInfo.GetInstance);
+ FCertificates := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 0, False,
+ TAsn1Set.GetTagged);
+ FCrls := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 1, False,
+ TAsn1Set.GetTagged);
+ FSignerInfos := TAsn1Utilities.Read(ASeq, LPos, TAsn1Set.GetInstance);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
constructor TPkcsSignedData.Create(const AVersion: IDerInteger;
@@ -2264,6 +2164,21 @@ function TPkcsSignedData.ToAsn1Object: IAsn1Object;
{ TMacData }
+class function TMacData.GetOptional(const AElement: IAsn1Encodable): IMacData;
+var
+ LSequence: IAsn1Sequence;
+begin
+ if AElement = nil then
+ raise EArgumentNilCryptoLibException.CreateRes(@SAsn1EncodableElementNil);
+ if Supports(AElement, IMacData, Result) then
+ Exit;
+ LSequence := TAsn1Sequence.GetOptional(AElement);
+ if LSequence <> nil then
+ Result := TMacData.Create(LSequence)
+ else
+ Result := nil;
+end;
+
class function TMacData.GetInstance(AObj: TObject): IMacData;
begin
if AObj = nil then
@@ -2317,31 +2232,19 @@ class function TMacData.GetTagged(const ATaggedObject: IAsn1TaggedObject;
constructor TMacData.Create(const ASeq: IAsn1Sequence);
var
- LCount, LPos: Int32;
+ LPos: Int32;
begin
inherited Create();
-
- LCount := ASeq.Count;
LPos := 0;
- if (LCount < 2) or (LCount > 3) then
- raise EArgumentCryptoLibException.CreateResFmt(@SPkcsBadSequenceSize, [LCount]);
-
- FMac := TDigestInfo.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
- FMacSalt := TAsn1OctetString.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
- FIterations := TAsn1Utilities.ReadOptional(ASeq, LPos, ReadOptionalDerInteger);
+ TAsn1Utilities.CheckSequenceSize(ASeq, 2, 3);
+ FMac := TAsn1Utilities.Read(ASeq, LPos, TDigestInfo.GetInstance);
+ FMacSalt := TAsn1Utilities.Read(ASeq, LPos, TAsn1OctetString.GetInstance);
+ FIterations := TAsn1Utilities.ReadOptional(ASeq, LPos, TDerInteger.GetOptional);
if FIterations = nil then
FIterations := TDerInteger.One;
-
- if LPos <> LCount then
- raise EArgumentCryptoLibException.CreateRes(@SUnexpectedElementsInSequence);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
-class function TMacData.ReadOptionalDerInteger(AEnc: IAsn1Encodable): IDerInteger;
-begin
- Result := TDerInteger.GetOptional(AEnc);
-end;
constructor TMacData.Create(const ADigInfo: IDigestInfo;
const ASalt: TCryptoLibByteArray; AIterationCount: Int32);
@@ -2461,25 +2364,18 @@ class function TPfx.GetTagged(const ATaggedObject: IAsn1TaggedObject;
constructor TPfx.Create(const ASeq: IAsn1Sequence);
var
- LCount: Int32;
+ LPos: Int32;
LVersion: IDerInteger;
begin
inherited Create();
-
- LCount := ASeq.Count;
- if (LCount < 2) or (LCount > 3) then
- raise EArgumentCryptoLibException.CreateResFmt(@SPkcsBadSequenceSize, [LCount]);
-
- LVersion := TDerInteger.GetInstance(ASeq[0]);
+ LPos := 0;
+ TAsn1Utilities.CheckSequenceSize(ASeq, 2, 3);
+ LVersion := TAsn1Utilities.Read(ASeq, LPos, TDerInteger.GetInstance);
if not LVersion.HasValue(3) then
raise EArgumentCryptoLibException.CreateRes(@SWrongVersionForPfxPdu);
-
- FContentInfo := TPkcsContentInfo.GetInstance(ASeq[1]);
-
- if LCount <= 2 then
- FMacData := nil
- else
- FMacData := TMacData.GetInstance(ASeq[2]);
+ FContentInfo := TAsn1Utilities.Read(ASeq, LPos, TPkcsContentInfo.GetInstance);
+ FMacData := TAsn1Utilities.ReadOptional(ASeq, LPos, TMacData.GetOptional);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
constructor TPfx.Create(const AContentInfo: IPkcsContentInfo;
@@ -2567,33 +2463,18 @@ class function TSafeBag.GetTagged(const ATaggedObject: IAsn1TaggedObject;
constructor TSafeBag.Create(const ASeq: IAsn1Sequence);
var
- LCount, LPos: Int32;
- LTagged: IAsn1TaggedObject;
+ LPos: Int32;
begin
inherited Create();
-
- LCount := ASeq.Count;
LPos := 0;
- if (LCount < 2) or (LCount > 3) then
- raise EArgumentCryptoLibException.CreateResFmt(@SPkcsBadSequenceSize, [LCount]);
-
- FBagID := TDerObjectIdentifier.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
-
- LTagged := TAsn1TaggedObject.GetContextInstance(ASeq[LPos], 0);
- FBagValue := LTagged.GetExplicitBaseObject();
- System.Inc(LPos);
-
- FBagAttributes := TAsn1Utilities.ReadOptional(ASeq, LPos, ReadOptionalAsn1Set);
-
- if LPos <> LCount then
- raise EArgumentCryptoLibException.CreateRes(@SUnexpectedElementsInSequence);
+ TAsn1Utilities.CheckSequenceSize(ASeq, 2, 3);
+ FBagID := TAsn1Utilities.Read(ASeq, LPos, TDerObjectIdentifier.GetInstance);
+ FBagValue := TAsn1Utilities.ReadContextTagged(ASeq, LPos, 0, True,
+ TAsn1Utilities.GetTaggedExplicitBaseObject);
+ FBagAttributes := TAsn1Utilities.ReadOptional(ASeq, LPos, TAsn1Set.GetOptional);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
-class function TSafeBag.ReadOptionalAsn1Set(AElement: IAsn1Encodable): IAsn1Set;
-begin
- Result := TAsn1Set.GetOptional(AElement);
-end;
constructor TSafeBag.Create(const ABagID: IDerObjectIdentifier;
const ABagValue: IAsn1Encodable);
@@ -2702,18 +2583,15 @@ class function TCertBag.GetTagged(const ATaggedObject: IAsn1TaggedObject;
constructor TCertBag.Create(const ASeq: IAsn1Sequence);
var
- LCount: Int32;
- LTagged: IAsn1TaggedObject;
+ LPos: Int32;
begin
inherited Create();
-
- LCount := ASeq.Count;
- if LCount <> 2 then
- raise EArgumentCryptoLibException.CreateResFmt(@SPkcsBadSequenceSize, [LCount]);
-
- FCertID := TDerObjectIdentifier.GetInstance(ASeq[0]);
- LTagged := TAsn1TaggedObject.GetContextInstance(ASeq[1], 0);
- FCertValue := LTagged.GetExplicitBaseObject();
+ LPos := 0;
+ TAsn1Utilities.CheckSequenceSize(ASeq, 2, 2);
+ FCertID := TAsn1Utilities.Read(ASeq, LPos, TDerObjectIdentifier.GetInstance);
+ FCertValue := TAsn1Utilities.ReadContextTagged(ASeq, LPos, 0, True,
+ TAsn1Utilities.GetTaggedExplicitBaseObject);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
constructor TCertBag.Create(const ACertID: IDerObjectIdentifier;
@@ -2899,20 +2777,17 @@ class function TPkcsEncryptedData.GetTagged(const ATaggedObject: IAsn1TaggedObje
constructor TPkcsEncryptedData.Create(const ASeq: IAsn1Sequence);
var
- LCount: Int32;
+ LPos: Int32;
LVersion: IDerInteger;
begin
inherited Create();
-
- LCount := ASeq.Count;
- if LCount <> 2 then
- raise EArgumentCryptoLibException.CreateResFmt(@SPkcsBadSequenceSize, [LCount]);
-
- LVersion := TDerInteger.GetInstance(ASeq[0]);
+ LPos := 0;
+ TAsn1Utilities.CheckSequenceSize(ASeq, 2, 2);
+ LVersion := TAsn1Utilities.Read(ASeq, LPos, TDerInteger.GetInstance);
if not LVersion.HasValue(0) then
raise EArgumentCryptoLibException.CreateRes(@SEncryptedDataVersionNotZero);
-
- FData := TAsn1Sequence.GetInstance(ASeq[1]);
+ FData := TAsn1Utilities.Read(ASeq, LPos, TAsn1Sequence.GetInstance);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
constructor TPkcsEncryptedData.Create(const AContentType: IDerObjectIdentifier;
diff --git a/CryptoLib/src/Asn1/Pkcs/ClpPkcsDHAsn1Objects.pas b/CryptoLib/src/Asn1/Pkcs/ClpPkcsDHAsn1Objects.pas
index 2c06299f..be8a1202 100644
--- a/CryptoLib/src/Asn1/Pkcs/ClpPkcsDHAsn1Objects.pas
+++ b/CryptoLib/src/Asn1/Pkcs/ClpPkcsDHAsn1Objects.pas
@@ -28,7 +28,8 @@ interface
ClpIAsn1Core,
ClpIPkcsDHAsn1Objects,
ClpBigInteger,
- ClpCryptoLibTypes;
+ ClpCryptoLibTypes,
+ ClpAsn1Utilities;
resourcestring
SBadSequenceSize = 'bad sequence size: %d';
@@ -73,18 +74,15 @@ implementation
constructor TDHParameter.Create(const ASeq: IAsn1Sequence);
var
- LCount: Int32;
+ LPos: Int32;
begin
inherited Create();
- LCount := ASeq.Count;
- if (LCount < 2) or (LCount > 3) then
- raise EArgumentCryptoLibException.CreateResFmt(@SBadSequenceSize, [LCount]);
- FP := TDerInteger.GetInstance(ASeq[0]);
- FG := TDerInteger.GetInstance(ASeq[1]);
- if LCount > 2 then
- FL := TDerInteger.GetInstance(ASeq[2])
- else
- FL := nil;
+ LPos := 0;
+ TAsn1Utilities.CheckSequenceSize(ASeq, 2, 3);
+ FP := TAsn1Utilities.Read(ASeq, LPos, TDerInteger.GetInstance);
+ FG := TAsn1Utilities.Read(ASeq, LPos, TDerInteger.GetInstance);
+ FL := TAsn1Utilities.ReadOptional(ASeq, LPos, TDerInteger.GetOptional);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
constructor TDHParameter.Create(const AP, AG: TBigInteger; AL: Int32);
diff --git a/CryptoLib/src/Asn1/Pkcs/ClpPkcsRsaAsn1Objects.pas b/CryptoLib/src/Asn1/Pkcs/ClpPkcsRsaAsn1Objects.pas
index 07476802..7315e08d 100644
--- a/CryptoLib/src/Asn1/Pkcs/ClpPkcsRsaAsn1Objects.pas
+++ b/CryptoLib/src/Asn1/Pkcs/ClpPkcsRsaAsn1Objects.pas
@@ -121,8 +121,6 @@ TRsassaPssParameters = class(TAsn1Encodable, IRsassaPssParameters)
FDefaultHashAlgorithm, FDefaultMaskGenAlgorithm: IAlgorithmIdentifier;
FDefaultSaltLength, FDefaultTrailerField: IDerInteger;
class constructor Create;
- class function GetTaggedAlgorithmIdentifier(ATagged: IAsn1TaggedObject; AState: Boolean): IAlgorithmIdentifier; static;
- class function GetTaggedDerInteger(ATagged: IAsn1TaggedObject; AState: Boolean): IDerInteger; static;
var
FHashAlgorithm: IAlgorithmIdentifier;
@@ -181,7 +179,6 @@ TRsaesOaepParameters = class(TAsn1Encodable, IRsaesOaepParameters)
FDefaultHashAlgorithm, FDefaultMaskGenAlgorithm,
FDefaultPSourceAlgorithm: IAlgorithmIdentifier;
class constructor Create;
- class function GetTaggedAlgorithmIdentifier(ATagged: IAsn1TaggedObject; AState: Boolean): IAlgorithmIdentifier; static;
var
FHashAlgorithm: IAlgorithmIdentifier;
@@ -278,26 +275,22 @@ class function TRsaPrivateKeyStructure.GetTagged(const ATaggedObject: IAsn1Tagge
constructor TRsaPrivateKeyStructure.Create(const ASeq: IAsn1Sequence);
var
- LCount: Int32;
+ LPos: Int32;
LVersion: IDerInteger;
begin
inherited Create();
-
- LCount := ASeq.Count;
- if LCount <> 9 then
- begin
- raise EArgumentCryptoLibException.CreateResFmt(@SBadSequenceSize, [LCount]);
- end;
-
- LVersion := TDerInteger.GetInstance(ASeq[0]);
- FModulus := TDerInteger.GetInstance(ASeq[1]).Value;
- FPublicExponent := TDerInteger.GetInstance(ASeq[2]).Value;
- FPrivateExponent := TDerInteger.GetInstance(ASeq[3]).Value;
- FPrime1 := TDerInteger.GetInstance(ASeq[4]).Value;
- FPrime2 := TDerInteger.GetInstance(ASeq[5]).Value;
- FExponent1 := TDerInteger.GetInstance(ASeq[6]).Value;
- FExponent2 := TDerInteger.GetInstance(ASeq[7]).Value;
- FCoefficient := TDerInteger.GetInstance(ASeq[8]).Value;
+ LPos := 0;
+ TAsn1Utilities.CheckSequenceSize(ASeq, 9, 9);
+ LVersion := TAsn1Utilities.Read(ASeq, LPos, TDerInteger.GetInstance);
+ FModulus := TAsn1Utilities.Read(ASeq, LPos, TDerInteger.GetInstance).Value;
+ FPublicExponent := TAsn1Utilities.Read(ASeq, LPos, TDerInteger.GetInstance).Value;
+ FPrivateExponent := TAsn1Utilities.Read(ASeq, LPos, TDerInteger.GetInstance).Value;
+ FPrime1 := TAsn1Utilities.Read(ASeq, LPos, TDerInteger.GetInstance).Value;
+ FPrime2 := TAsn1Utilities.Read(ASeq, LPos, TDerInteger.GetInstance).Value;
+ FExponent1 := TAsn1Utilities.Read(ASeq, LPos, TDerInteger.GetInstance).Value;
+ FExponent2 := TAsn1Utilities.Read(ASeq, LPos, TDerInteger.GetInstance).Value;
+ FCoefficient := TAsn1Utilities.Read(ASeq, LPos, TDerInteger.GetInstance).Value;
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
if not LVersion.HasValue(0) then
raise EArgumentCryptoLibException.CreateRes(@SWrongVersionForRsaPrivateKey);
@@ -454,48 +447,34 @@ class function TRsassaPssParameters.GetTagged(const ATaggedObject: IAsn1TaggedOb
Result := TRsassaPssParameters.Create(TAsn1Sequence.GetTagged(ATaggedObject, ADeclaredExplicit));
end;
-class function TRsassaPssParameters.GetTaggedAlgorithmIdentifier(ATagged: IAsn1TaggedObject; AState: Boolean): IAlgorithmIdentifier;
-begin
- Result := TAlgorithmIdentifier.GetTagged(ATagged, AState);
-end;
-
-class function TRsassaPssParameters.GetTaggedDerInteger(ATagged: IAsn1TaggedObject; AState: Boolean): IDerInteger;
-begin
- Result := TDerInteger.GetTagged(ATagged, AState);
-end;
-
constructor TRsassaPssParameters.Create(const ASeq: IAsn1Sequence);
var
- LCount, LPos: Int32;
+ LPos: Int32;
begin
inherited Create();
- LCount := ASeq.Count;
LPos := 0;
- if (LCount < 0) or (LCount > 4) then
- raise EArgumentCryptoLibException.CreateResFmt(@SBadSequenceSize, [LCount]);
-
- FHashAlgorithm := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 0, True,
- GetTaggedAlgorithmIdentifier);
+ TAsn1Utilities.CheckSequenceSize(ASeq, 0, 4);
+ FHashAlgorithm := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 0, True,
+ TAlgorithmIdentifier.GetTagged);
if FHashAlgorithm = nil then
FHashAlgorithm := DefaultHashAlgorithm;
- FMaskGenAlgorithm := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 1, True,
- GetTaggedAlgorithmIdentifier);
+ FMaskGenAlgorithm := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 1, True,
+ TAlgorithmIdentifier.GetTagged);
if FMaskGenAlgorithm = nil then
FMaskGenAlgorithm := DefaultMaskGenAlgorithm;
- FSaltLength := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 2, True,
- GetTaggedDerInteger);
+ FSaltLength := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 2, True,
+ TDerInteger.GetTagged);
if FSaltLength = nil then
FSaltLength := DefaultSaltLength;
- FTrailerField := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 3, True,
- GetTaggedDerInteger);
+ FTrailerField := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 3, True,
+ TDerInteger.GetTagged);
if FTrailerField = nil then
FTrailerField := DefaultTrailerField;
- if LPos <> LCount then
- raise EArgumentCryptoLibException.CreateRes(@SUnexpectedElementsInSequence);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
constructor TRsassaPssParameters.Create;
@@ -641,38 +620,29 @@ class function TRsaesOaepParameters.GetTagged(const ATaggedObject: IAsn1TaggedOb
Result := TRsaesOaepParameters.Create(TAsn1Sequence.GetTagged(ATaggedObject, ADeclaredExplicit));
end;
-class function TRsaesOaepParameters.GetTaggedAlgorithmIdentifier(ATagged: IAsn1TaggedObject; AState: Boolean): IAlgorithmIdentifier;
-begin
- Result := TAlgorithmIdentifier.GetTagged(ATagged, AState);
-end;
-
constructor TRsaesOaepParameters.Create(const ASeq: IAsn1Sequence);
var
- LCount, LPos: Int32;
+ LPos: Int32;
begin
inherited Create();
- LCount := ASeq.Count;
LPos := 0;
- if (LCount < 0) or (LCount > 3) then
- raise EArgumentCryptoLibException.CreateResFmt(@SBadSequenceSize, [LCount]);
-
- FHashAlgorithm := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 0, True,
- GetTaggedAlgorithmIdentifier);
+ TAsn1Utilities.CheckSequenceSize(ASeq, 0, 3);
+ FHashAlgorithm := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 0, True,
+ TAlgorithmIdentifier.GetTagged);
if FHashAlgorithm = nil then
FHashAlgorithm := DefaultHashAlgorithm;
- FMaskGenAlgorithm := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 1, True,
- GetTaggedAlgorithmIdentifier);
+ FMaskGenAlgorithm := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 1, True,
+ TAlgorithmIdentifier.GetTagged);
if FMaskGenAlgorithm = nil then
FMaskGenAlgorithm := DefaultMaskGenAlgorithm;
- FPSourceAlgorithm := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 2, True,
- GetTaggedAlgorithmIdentifier);
+ FPSourceAlgorithm := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 2, True,
+ TAlgorithmIdentifier.GetTagged);
if FPSourceAlgorithm = nil then
FPSourceAlgorithm := DefaultPSourceAlgorithm;
- if LPos <> LCount then
- raise EArgumentCryptoLibException.CreateRes(@SUnexpectedElementsInSequence);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
constructor TRsaesOaepParameters.Create;
diff --git a/CryptoLib/src/Asn1/Sec/ClpSecECAsn1Objects.pas b/CryptoLib/src/Asn1/Sec/ClpSecECAsn1Objects.pas
index 3d2ee44d..35d59e66 100644
--- a/CryptoLib/src/Asn1/Sec/ClpSecECAsn1Objects.pas
+++ b/CryptoLib/src/Asn1/Sec/ClpSecECAsn1Objects.pas
@@ -33,10 +33,8 @@ interface
ClpAsn1Utilities;
resourcestring
- SBadSequenceSize = 'bad sequence size: %d';
SKeyNil = 'key cannot be nil';
SOrderBitLengthTooSmall = 'order must be at least the key bit length';
- SUnexpectedElementsInSequence = 'unexpected elements in sequence';
SPrivateKeyNil = 'private key cannot be nil';
@@ -53,9 +51,6 @@ TECPrivateKeyStructure = class(TAsn1Encodable, IECPrivateKeyStructure)
FParameters: IAsn1Encodable;
FPublicKey: IDerBitString;
- class function GetTaggedExplicitBaseObject(ATagged: IAsn1TaggedObject; AState: Boolean): IAsn1Encodable; static;
- class function GetTaggedDerBitString(ATagged: IAsn1TaggedObject; AState: Boolean): IDerBitString; static;
-
strict protected
function GetVersion: IDerInteger;
function GetPrivateKey: IAsn1OctetString;
@@ -146,41 +141,20 @@ class function TECPrivateKeyStructure.GetTagged(const ATaggedObject: IAsn1Tagged
Result := TECPrivateKeyStructure.Create(TAsn1Sequence.GetTagged(ATaggedObject, ADeclaredExplicit));
end;
-class function TECPrivateKeyStructure.GetTaggedExplicitBaseObject(ATagged: IAsn1TaggedObject; AState: Boolean): IAsn1Encodable;
-begin
- Result := ATagged.GetExplicitBaseObject();
-end;
-
-class function TECPrivateKeyStructure.GetTaggedDerBitString(ATagged: IAsn1TaggedObject; AState: Boolean): IDerBitString;
-begin
- Result := TDerBitString.GetTagged(ATagged, AState);
-end;
-
constructor TECPrivateKeyStructure.Create(const ASeq: IAsn1Sequence);
var
- LCount, LPos: Int32;
+ LPos: Int32;
begin
inherited Create();
- LCount := ASeq.Count;
LPos := 0;
-
- if (LCount < 2) or (LCount > 4) then
- raise EArgumentCryptoLibException.CreateResFmt(@SBadSequenceSize, [LCount]);
-
- FVersion := TDerInteger.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
-
- FPrivateKey := TAsn1OctetString.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
-
- FParameters := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 0, True,
- GetTaggedExplicitBaseObject);
-
- FPublicKey := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 1, True,
- GetTaggedDerBitString);
-
- if LPos <> LCount then
- raise EArgumentCryptoLibException.CreateRes(@SUnexpectedElementsInSequence);
+ TAsn1Utilities.CheckSequenceSize(ASeq, 2, 4);
+ FVersion := TAsn1Utilities.Read(ASeq, LPos, TDerInteger.GetInstance);
+ FPrivateKey := TAsn1Utilities.Read(ASeq, LPos, TAsn1OctetString.GetInstance);
+ FParameters := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 0, True,
+ TAsn1Utilities.GetTaggedExplicitBaseObject);
+ FPublicKey := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 1, True,
+ TDerBitString.GetTagged);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
constructor TECPrivateKeyStructure.Create(AOrderBitLength: Int32; const AKey: TBigInteger);
diff --git a/CryptoLib/src/Asn1/X500/ClpX500Asn1Objects.pas b/CryptoLib/src/Asn1/X500/ClpX500Asn1Objects.pas
index 7b57f50c..eab6e48b 100644
--- a/CryptoLib/src/Asn1/X500/ClpX500Asn1Objects.pas
+++ b/CryptoLib/src/Asn1/X500/ClpX500Asn1Objects.pas
@@ -230,16 +230,14 @@ class function TAttributeTypeAndValue.GetTagged(const ATaggedObject: IAsn1Tagged
constructor TAttributeTypeAndValue.Create(const ASeq: IAsn1Sequence);
var
- LCount: Int32;
+ LPos: Int32;
begin
inherited Create();
-
- LCount := ASeq.Count;
- if LCount <> 2 then
- raise EArgumentCryptoLibException.CreateResFmt(@SBadSequenceSize, [LCount]);
-
- FAttrType := TDerObjectIdentifier.GetInstance(ASeq[0]);
- FValue := ASeq[1];
+ LPos := 0;
+ TAsn1Utilities.CheckSequenceSize(ASeq, 2, 2);
+ FAttrType := TAsn1Utilities.Read(ASeq, LPos, TDerObjectIdentifier.GetInstance);
+ FValue := TAsn1Utilities.ReadEncodable(ASeq, LPos);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
constructor TAttributeTypeAndValue.Create(const AAttrType: IDerObjectIdentifier;
diff --git a/CryptoLib/src/Asn1/X509/ClpX509Asn1Objects.pas b/CryptoLib/src/Asn1/X509/ClpX509Asn1Objects.pas
index 468ca9f4..5979a6e4 100644
--- a/CryptoLib/src/Asn1/X509/ClpX509Asn1Objects.pas
+++ b/CryptoLib/src/Asn1/X509/ClpX509Asn1Objects.pas
@@ -257,10 +257,6 @@ TDeltaCertificateDescriptor = class(TAsn1Encodable, IAsn1Encodable,
strict private
procedure ImplCreate(const ASeq: IAsn1Sequence);
- class function GetTaggedAlgorithmIdentifier(ATagged: IAsn1TaggedObject; AState: Boolean): IAlgorithmIdentifier; static;
- class function GetTaggedX509Name(ATagged: IAsn1TaggedObject; AState: Boolean): IX509Name; static;
- class function GetTaggedValidity(ATagged: IAsn1TaggedObject; AState: Boolean): IValidity; static;
- class function GetTaggedX509Extensions(ATagged: IAsn1TaggedObject; AState: Boolean): IX509Extensions; static;
strict protected
function GetSerialNumber: IDerInteger;
@@ -462,9 +458,6 @@ TAuthorityKeyIdentifier = class(TAsn1Encodable, IAuthorityKeyIdentifier)
FAuthorityCertSerialNumber: IDerInteger;
class procedure CheckIssuerAndSerial(const ACertIssuer: IGeneralNames; const ACertSerial: IDerInteger); static;
- class function GetTaggedAsn1OctetString(ATagged: IAsn1TaggedObject; AState: Boolean): IAsn1OctetString; static;
- class function GetTaggedGeneralNames(ATagged: IAsn1TaggedObject; AState: Boolean): IGeneralNames; static;
- class function GetTaggedDerInteger(ATagged: IAsn1TaggedObject; AState: Boolean): IDerInteger; static;
strict protected
function GetKeyIdentifier: IAsn1OctetString;
@@ -1193,7 +1186,6 @@ TCrlEntry = class(TAsn1Encodable, ICrlEntry)
FRevocationDate: ITime;
FCrlEntryExtensions: IX509Extensions;
- class function ReadOptionalX509Extensions(AElement: IAsn1Encodable): IX509Extensions; static;
strict protected
function GetUserCertificate: IDerInteger;
@@ -1330,8 +1322,6 @@ TBasicConstraints = class(TAsn1Encodable, IBasicConstraints)
FCA: IDerBoolean;
FPathLenConstraint: IDerInteger;
- class function ReadOptionalDerBoolean(AElement: IAsn1Encodable): IDerBoolean; static;
- class function ReadOptionalDerInteger(AElement: IAsn1Encodable): IDerInteger; static;
strict protected
function IsCA: Boolean;
@@ -1463,9 +1453,6 @@ TTbsCertificateStructure = class(TAsn1Encodable, ITbsCertificateStructure)
FExtensions: IX509Extensions;
FSeq: IAsn1Sequence;
- class function GetTaggedDerInteger(ATagged: IAsn1TaggedObject; AState: Boolean): IDerInteger; static;
- class function GetTaggedDerBitString(ATagged: IAsn1TaggedObject; AState: Boolean): IDerBitString; static;
- class function GetTaggedX509Extensions(ATagged: IAsn1TaggedObject; AState: Boolean): IX509Extensions; static;
strict protected
function GetVersion: Int32;
@@ -1602,7 +1589,6 @@ TCertificatePair = class(TAsn1Encodable, ICertificatePair)
FReverse: IX509CertificateStructure;
procedure Validate;
- class function GetTaggedX509CertificateStructure(ATagged: IAsn1TaggedObject; AState: Boolean): IX509CertificateStructure; static;
strict protected
function GetForward: IX509CertificateStructure;
@@ -1752,7 +1738,6 @@ TIssuerSerial = class(TAsn1Encodable, IIssuerSerial)
FSerial: IDerInteger;
FIssuerUid: IDerBitString;
- class function ReadOptionalDerBitString(AElement: IAsn1Encodable): IDerBitString; static;
strict protected
function GetIssuer: IGeneralNames;
@@ -1797,9 +1782,6 @@ TV2Form = class(TAsn1Encodable, IV2Form)
FBaseCertificateID: IIssuerSerial;
FObjectDigestInfo: IObjectDigestInfo;
- class function ReadOptionalGeneralNames(AElement: IAsn1Encodable): IGeneralNames; static;
- class function GetTaggedIssuerSerial(ATagged: IAsn1TaggedObject; AState: Boolean): IIssuerSerial; static;
- class function GetTaggedObjectDigestInfo(ATagged: IAsn1TaggedObject; AState: Boolean): IObjectDigestInfo; static;
strict protected
function GetIssuerName: IGeneralNames;
@@ -1846,7 +1828,6 @@ TObjectDigestInfo = class(TAsn1Encodable, IObjectDigestInfo)
FDigestAlgorithm: IAlgorithmIdentifier;
FObjectDigest: IDerBitString;
- class function ReadOptionalDerObjectIdentifier(AElement: IAsn1Encodable): IDerObjectIdentifier; static;
public
const
@@ -2028,10 +2009,6 @@ TTbsCertificateList = class(TAsn1Encodable, ITbsCertificateList)
FRevokedCertificates: IAsn1Sequence;
FCrlExtensions: IX509Extensions;
- class function ReadOptionalDerInteger(AElement: IAsn1Encodable): IDerInteger; static;
- class function ReadOptionalTime(AElement: IAsn1Encodable): ITime; static;
- class function ReadOptionalAsn1Sequence(AElement: IAsn1Encodable): IAsn1Sequence; static;
- class function GetTaggedX509Extensions(ATagged: IAsn1TaggedObject; AState: Boolean): IX509Extensions; static;
class function ElementToCrlEntry(AElement: IAsn1Encodable): ICrlEntry; static;
strict protected
@@ -2078,9 +2055,7 @@ TDistributionPoint = class(TAsn1Encodable, IDistributionPoint)
FReasons: IReasonFlags;
FCrlIssuer: IGeneralNames;
- class function GetTaggedDistributionPointName(ATagged: IAsn1TaggedObject; AState: Boolean): IDistributionPointName; static;
- class function GetTaggedReasonFlags(ATagged: IAsn1TaggedObject; AState: Boolean): IReasonFlags; static;
- class function GetTaggedGeneralNames(ATagged: IAsn1TaggedObject; AState: Boolean): IGeneralNames; static;
+ class function GetTaggedReasonFlags(const ATagged: IAsn1TaggedObject; AState: Boolean): IReasonFlags; static;
strict protected
function GetDistributionPointName: IDistributionPointName;
@@ -2137,9 +2112,7 @@ TIssuingDistributionPoint = class(TAsn1Encodable, IIssuingDistributionPoint)
FOnlyContainsAttributeCerts: IDerBoolean;
FSeq: IAsn1Sequence;
- class function GetTaggedDistributionPointName(ATagged: IAsn1TaggedObject; AState: Boolean): IDistributionPointName; static;
- class function GetTaggedDerBoolean(ATagged: IAsn1TaggedObject; AState: Boolean): IDerBoolean; static;
- class function GetTaggedReasonFlags(ATagged: IAsn1TaggedObject; AState: Boolean): IReasonFlags; static;
+ class function GetTaggedReasonFlags(const ATagged: IAsn1TaggedObject; AState: Boolean): IReasonFlags; static;
strict protected
function GetDistributionPoint: IDistributionPointName;
@@ -2302,9 +2275,6 @@ THolder = class(TAsn1Encodable, IHolder)
FObjectDigestInfo: IObjectDigestInfo;
FVersion: Int32;
- class function GetTaggedIssuerSerial(ATagged: IAsn1TaggedObject; AState: Boolean): IIssuerSerial; static;
- class function GetTaggedGeneralNames(ATagged: IAsn1TaggedObject; AState: Boolean): IGeneralNames; static;
- class function GetTaggedObjectDigestInfo(ATagged: IAsn1TaggedObject; AState: Boolean): IObjectDigestInfo; static;
strict protected
function GetVersion: Int32;
@@ -2399,9 +2369,6 @@ TAttributeCertificateInfo = class(TAsn1Encodable, IAttributeCertificateInfo)
FIssuerUniqueID: IDerBitString;
FExtensions: IX509Extensions;
- class function ReadOptionalDerInteger(AElement: IAsn1Encodable): IDerInteger; static;
- class function ReadOptionalDerBitString(AElement: IAsn1Encodable): IDerBitString; static;
- class function ReadOptionalX509Extensions(AElement: IAsn1Encodable): IX509Extensions; static;
strict protected
function GetVersion: IDerInteger;
@@ -2546,21 +2513,14 @@ class function TAlgorithmIdentifier.GetTagged(const ATaggedObject: IAsn1TaggedOb
constructor TAlgorithmIdentifier.Create(const ASeq: IAsn1Sequence);
var
- LCount: Int32;
+ LPos: Int32;
begin
inherited Create();
-
- LCount := ASeq.Count;
- if (LCount < 1) or (LCount > 2) then
- begin
- raise EArgumentCryptoLibException.CreateResFmt(@SBadSequenceSize, [LCount]);
- end;
-
- FAlgorithm := TDerObjectIdentifier.GetInstance(ASeq[0]);
- if LCount < 2 then
- FParameters := nil
- else
- FParameters := ASeq[1];
+ LPos := 0;
+ TAsn1Utilities.CheckSequenceSize(ASeq, 1, 2);
+ FAlgorithm := TAsn1Utilities.Read(ASeq, LPos, TDerObjectIdentifier.GetInstance);
+ FParameters := TAsn1Utilities.ReadOptional(ASeq, LPos, TAsn1Utilities.GetEncodableIdentity);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
constructor TAlgorithmIdentifier.Create(const AAlgorithm: IDerObjectIdentifier);
@@ -2655,18 +2615,14 @@ class function TDigestInfo.GetTagged(const ATaggedObject: IAsn1TaggedObject;
constructor TDigestInfo.Create(const ASeq: IAsn1Sequence);
var
- LCount: Int32;
+ LPos: Int32;
begin
inherited Create();
-
- LCount := ASeq.Count;
- if LCount <> 2 then
- begin
- raise EArgumentCryptoLibException.CreateResFmt(@SBadSequenceSize, [LCount]);
- end;
-
- FDigestAlgorithm := TAlgorithmIdentifier.GetInstance(ASeq[0]);
- FDigest := TAsn1OctetString.GetInstance(ASeq[1]);
+ LPos := 0;
+ TAsn1Utilities.CheckSequenceSize(ASeq, 2, 2);
+ FDigestAlgorithm := TAsn1Utilities.Read(ASeq, LPos, TAlgorithmIdentifier.GetInstance);
+ FDigest := TAsn1Utilities.Read(ASeq, LPos, TAsn1OctetString.GetInstance);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
constructor TDigestInfo.Create(const AAlgId: IAlgorithmIdentifier;
@@ -2724,62 +2680,26 @@ function TDigestInfo.ToAsn1Object: IAsn1Object;
{ TDeltaCertificateDescriptor }
-class function TDeltaCertificateDescriptor.GetTaggedAlgorithmIdentifier(ATagged: IAsn1TaggedObject; AState: Boolean): IAlgorithmIdentifier;
-begin
- Result := TAlgorithmIdentifier.GetTagged(ATagged, AState);
-end;
-
-class function TDeltaCertificateDescriptor.GetTaggedX509Name(ATagged: IAsn1TaggedObject; AState: Boolean): IX509Name;
-begin
- Result := TX509Name.GetTagged(ATagged, AState);
-end;
-
-class function TDeltaCertificateDescriptor.GetTaggedValidity(ATagged: IAsn1TaggedObject; AState: Boolean): IValidity;
-begin
- Result := TValidity.GetTagged(ATagged, AState);
-end;
-
-class function TDeltaCertificateDescriptor.GetTaggedX509Extensions(ATagged: IAsn1TaggedObject; AState: Boolean): IX509Extensions;
-begin
- Result := TX509Extensions.GetTagged(ATagged, AState);
-end;
-
procedure TDeltaCertificateDescriptor.ImplCreate(const ASeq: IAsn1Sequence);
var
- LCount, LPos: Int32;
+ LPos: Int32;
begin
- LCount := ASeq.Count;
LPos := 0;
- if (LCount < 3) or (LCount > 8) then
- raise EArgumentCryptoLibException.CreateResFmt(@SBadSequenceSize, [LCount]);
-
- FSerialNumber := TDerInteger.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
-
- FSignature := TAsn1Utilities.ReadOptionalContextTagged(
- ASeq, LPos, 0, True,
- GetTaggedAlgorithmIdentifier);
-
- FIssuer := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 1, True,
- GetTaggedX509Name);
-
- FValidity := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 2, True,
- GetTaggedValidity);
-
- FSubject := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 3, True,
- GetTaggedX509Name);
-
- FSubjectPublicKeyInfo := TSubjectPublicKeyInfo.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
-
- FExtensions := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 4, True,
- GetTaggedX509Extensions);
-
- FSignatureValue := TDerBitString.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
-
- if LPos <> LCount then
- raise EArgumentCryptoLibException.CreateRes(@SUnexpectedElementsInSequence);
+ TAsn1Utilities.CheckSequenceSize(ASeq, 3, 8);
+ FSerialNumber := TAsn1Utilities.Read(ASeq, LPos, TDerInteger.GetInstance);
+ FSignature := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 0, True,
+ TAlgorithmIdentifier.GetTagged);
+ FIssuer := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 1, True,
+ TX509Name.GetTagged);
+ FValidity := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 2, True,
+ TValidity.GetTagged);
+ FSubject := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 3, True,
+ TX509Name.GetTagged);
+ FSubjectPublicKeyInfo := TAsn1Utilities.Read(ASeq, LPos, TSubjectPublicKeyInfo.GetInstance);
+ FExtensions := TAsn1Utilities.ReadOptionalContextTagged(ASeq, LPos, 4, True,
+ TX509Extensions.GetTagged);
+ FSignatureValue := TAsn1Utilities.Read(ASeq, LPos, TDerBitString.GetInstance);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
constructor TDeltaCertificateDescriptor.Create(const ASeq: IAsn1Sequence);
@@ -3170,18 +3090,14 @@ class function TValidity.GetTagged(const ATaggedObject: IAsn1TaggedObject;
constructor TValidity.Create(const ASeq: IAsn1Sequence);
var
- LCount: Int32;
+ LPos: Int32;
begin
inherited Create();
-
- LCount := ASeq.Count;
- if LCount <> 2 then
- begin
- raise EArgumentCryptoLibException.CreateResFmt(@SBadSequenceSize, [LCount]);
- end;
-
- FNotBefore := TTime.GetInstance(ASeq[0]);
- FNotAfter := TTime.GetInstance(ASeq[1]);
+ LPos := 0;
+ TAsn1Utilities.CheckSequenceSize(ASeq, 2, 2);
+ FNotBefore := TAsn1Utilities.Read(ASeq, LPos, TTime.GetInstance);
+ FNotAfter := TAsn1Utilities.Read(ASeq, LPos, TTime.GetInstance);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
constructor TValidity.Create(const ANotBefore, ANotAfter: ITime);
@@ -3270,32 +3186,17 @@ class function TCrlEntry.GetTagged(const ATaggedObject: IAsn1TaggedObject;
Result := TCrlEntry.Create(TAsn1Sequence.GetTagged(ATaggedObject, ADeclaredExplicit));
end;
-class function TCrlEntry.ReadOptionalX509Extensions(AElement: IAsn1Encodable): IX509Extensions;
-begin
- Result := TX509Extensions.GetOptional(AElement);
-end;
-
constructor TCrlEntry.Create(const ASeq: IAsn1Sequence);
var
- LCount, LPos: Int32;
+ LPos: Int32;
begin
inherited Create();
-
- LCount := ASeq.Count;
LPos := 0;
- if (LCount < 2) or (LCount > 3) then
- raise EArgumentCryptoLibException.CreateResFmt(@SBadSequenceSize, [LCount]);
-
- FUserCertificate := TDerInteger.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
- FRevocationDate := TTime.GetInstance(ASeq[LPos]);
- System.Inc(LPos);
- FCrlEntryExtensions := TAsn1Utilities.ReadOptional(ASeq, LPos,
- ReadOptionalX509Extensions);
-
- if LPos <> LCount then
- raise EArgumentCryptoLibException.CreateRes(@SUnexpectedElementsInSequence);
-
+ TAsn1Utilities.CheckSequenceSize(ASeq, 2, 3);
+ FUserCertificate := TAsn1Utilities.Read(ASeq, LPos, TDerInteger.GetInstance);
+ FRevocationDate := TAsn1Utilities.Read(ASeq, LPos, TTime.GetInstance);
+ FCrlEntryExtensions := TAsn1Utilities.ReadOptional(ASeq, LPos, TX509Extensions.GetOptional);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
FSeq := ASeq;
end;
@@ -3631,39 +3532,18 @@ class function TBasicConstraints.GetTagged(const ATaggedObject: IAsn1TaggedObjec
Result := TBasicConstraints.Create(TAsn1Sequence.GetTagged(ATaggedObject, ADeclaredExplicit));
end;
-class function TBasicConstraints.ReadOptionalDerBoolean(AElement: IAsn1Encodable): IDerBoolean;
-begin
- Result := TDerBoolean.GetOptional(AElement);
-end;
-
-class function TBasicConstraints.ReadOptionalDerInteger(AElement: IAsn1Encodable): IDerInteger;
-begin
- Result := TDerInteger.GetOptional(AElement);
-end;
-
constructor TBasicConstraints.Create(const ASeq: IAsn1Sequence);
var
- LCount, LPos: Int32;
+ LPos: Int32;
begin
inherited Create();
-
- LCount := ASeq.Count;
LPos := 0;
- if (LCount < 0) or (LCount > 2) then
- begin
- raise EArgumentCryptoLibException.CreateResFmt(@SBadSequenceSize, [LCount]);
- end;
-
- FCA := TAsn1Utilities.ReadOptional(ASeq, LPos, ReadOptionalDerBoolean);
+ TAsn1Utilities.CheckSequenceSize(ASeq, 0, 2);
+ FCA := TAsn1Utilities.ReadOptional(ASeq, LPos, TDerBoolean.GetOptional);
if FCA = nil then
FCA := TDerBoolean.False;
-
- FPathLenConstraint := TAsn1Utilities.ReadOptional(ASeq, LPos, ReadOptionalDerInteger);
-
- if LPos <> LCount then
- begin
- raise EArgumentCryptoLibException.CreateRes(@SUnexpectedElementsInSequence);
- end;
+ FPathLenConstraint := TAsn1Utilities.ReadOptional(ASeq, LPos, TDerInteger.GetOptional);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
constructor TBasicConstraints.Create(ACA: Boolean);
@@ -3789,18 +3669,14 @@ class function TSubjectPublicKeyInfo.GetTagged(const ATaggedObject: IAsn1TaggedO
constructor TSubjectPublicKeyInfo.Create(const ASeq: IAsn1Sequence);
var
- LCount: Int32;
+ LPos: Int32;
begin
inherited Create();
-
- LCount := ASeq.Count;
- if LCount <> 2 then
- begin
- raise EArgumentCryptoLibException.CreateResFmt(@SBadSequenceSize, [LCount]);
- end;
-
- FAlgorithm := TAlgorithmIdentifier.GetInstance(ASeq[0]);
- FPublicKey := TDerBitString.GetInstance(ASeq[1]);
+ LPos := 0;
+ TAsn1Utilities.CheckSequenceSize(ASeq, 2, 2);
+ FAlgorithm := TAsn1Utilities.Read(ASeq, LPos, TAlgorithmIdentifier.GetInstance);
+ FPublicKey := TAsn1Utilities.Read(ASeq, LPos, TDerBitString.GetInstance);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
constructor TSubjectPublicKeyInfo.Create(const AAlgID: IAlgorithmIdentifier;
@@ -3904,18 +3780,14 @@ class function TSubjectAltPublicKeyInfo.FromExtensions(const AExtensions: IX509E
constructor TSubjectAltPublicKeyInfo.Create(const ASeq: IAsn1Sequence);
var
- LCount: Int32;
+ LPos: Int32;
begin
inherited Create();
-
- LCount := ASeq.Count;
- if LCount <> 2 then
- begin
- raise EArgumentCryptoLibException.CreateResFmt(@SBadSequenceSize, [LCount]);
- end;
-
- FAlgorithm := TAlgorithmIdentifier.GetInstance(ASeq[0]);
- FSubjectAltPublicKey := TDerBitString.GetInstance(ASeq[1]);
+ LPos := 0;
+ TAsn1Utilities.CheckSequenceSize(ASeq, 2, 2);
+ FAlgorithm := TAsn1Utilities.Read(ASeq, LPos, TAlgorithmIdentifier.GetInstance);
+ FSubjectAltPublicKey := TAsn1Utilities.Read(ASeq, LPos, TDerBitString.GetInstance);
+ TAsn1Utilities.RequireEndOfSequence(ASeq, LPos);
end;
constructor TSubjectAltPublicKeyInfo.Create(const AAlgorithm: IAlgorithmIdentifier;
@@ -4005,88 +3877,48 @@ class function TTbsCertificateStructure.GetTagged(const ATaggedObject: IAsn1Tagg
Result := TTbsCertificateStructure.Create(TAsn1Sequence.GetTagged(ATaggedObject, ADeclaredExplicit));
end;
-class function TTbsCertificateStructure.GetTaggedDerInteger(ATagged: IAsn1TaggedObject; AState: Boolean): IDerInteger;
-begin
- Result := TDerInteger.GetTagged(ATagged, AState);
-end;
-
-class function TTbsCertificateStructure.GetTaggedDerBitString(ATagged: IAsn1TaggedObject; AState: Boolean): IDerBitString;
-begin
- Result := TDerBitString.GetTagged(ATagged, AState);
-end;
-
-class function TTbsCertificateStructure.GetTaggedX509Extensions(ATagged: IAsn1TaggedObject; AState: Boolean): IX509Extensions;
-begin
- Result := TX509Extensions.GetTagged(ATagged, AState);
-end;
-
constructor TTbsCertificateStructure.Create(const ASeq: IAsn1Sequence);
var
- LCount, LPos: Int32;
+ LPos: Int32;
LIsV1, LIsV2: Boolean;
begin
inherited Create();
-
- LCount := ASeq.Count;
LPos := 0;
- if (LCount < 6) or (LCount > 10) then
- begin
- raise EArgumentCryptoLibException.CreateResFmt(@SBadSequenceSize, [LCount]);
- end;
+ TAsn1Utilities.CheckSequenceSize(ASeq, 6, 10);
- FVersion := TAsn1Utilities.ReadOptionalContextTagged