Skip to content

Commit e6337ab

Browse files
committed
Add RFC 5280 Extension types, document X.509 cert/CRL generators
1 parent fc6eb38 commit e6337ab

7 files changed

Lines changed: 824 additions & 6 deletions

File tree

CryptoLib.Tests/src/Asn1/X509/X509ExtensionsTests.pas

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ interface
4040
ClpAsn1Core,
4141
ClpIAsn1Core,
4242
ClpCryptoLibTypes,
43+
ClpArrayUtilities,
4344
CryptoLibTestBase;
4445

4546
type
@@ -58,6 +59,9 @@ TX509ExtensionsTest = class(TCryptoLibAlgorithmTestCase)
5859
procedure TestDuplicateExtensions;
5960
procedure TestAllowedDuplicateExtensions;
6061
procedure TestEqualsAndEquivalent;
62+
procedure TestExtensionRoundTrip;
63+
procedure TestExtensionsBridge;
64+
procedure TestExtensionsGeneratorIExtension;
6165

6266
end;
6367

@@ -243,6 +247,80 @@ procedure TX509ExtensionsTest.TestEqualsAndEquivalent;
243247
end;
244248
end;
245249

250+
procedure TX509ExtensionsTest.TestExtensionRoundTrip;
251+
var
252+
LExt: IExtension;
253+
LDecoded: IExtension;
254+
LBytes: TCryptoLibByteArray;
255+
begin
256+
LExt := TExtension.Create(FOid1, TDerBoolean.False,
257+
TDerOctetString.FromContents([$01, $02, $03]));
258+
LBytes := LExt.GetEncoded();
259+
LDecoded := TExtension.GetInstance(LBytes);
260+
CheckTrue(LDecoded.ExtnID.Equals(FOid1), 'extnID');
261+
CheckTrue(LDecoded.Critical.IsFalse, 'critical false');
262+
CheckTrue(TArrayUtilities.AreEqual(LDecoded.ExtnValue.GetOctets(), LExt.ExtnValue.GetOctets()),
263+
'extnValue');
264+
265+
LExt := TExtension.Create(FOid2, TDerBoolean.True,
266+
TDerOctetString.FromContents([$0A]));
267+
LBytes := LExt.GetEncoded();
268+
LDecoded := TExtension.GetInstance(LBytes);
269+
CheckTrue(LDecoded.Critical.IsTrue, 'critical true');
270+
end;
271+
272+
procedure TX509ExtensionsTest.TestExtensionsBridge;
273+
var
274+
LGen: IX509ExtensionsGenerator;
275+
LX509Exts: IX509Extensions;
276+
LExts, LRoundTrip: IExtensions;
277+
LBytes: TCryptoLibByteArray;
278+
begin
279+
LGen := TX509ExtensionsGenerator.Create();
280+
LGen.AddExtension(FOid1, True, TCryptoLibByteArray.Create(1, 2));
281+
LGen.AddExtension(FOid2, False, TCryptoLibByteArray.Create(3));
282+
LX509Exts := LGen.Generate();
283+
284+
LExts := TExtensions.FromX509Extensions(LX509Exts);
285+
CheckTrue(LExts.Count = 2, 'extensions count');
286+
CheckTrue(LExts.Equivalent(TExtensions.FromX509Extensions(LX509Exts)), 'self equivalent');
287+
288+
LRoundTrip := TExtensions.FromX509Extensions(TExtensions.ToX509Extensions(LExts));
289+
CheckTrue(LExts.Equivalent(LRoundTrip), 'bridge round-trip');
290+
291+
LBytes := LExts.GetEncoded();
292+
CheckTrue(TExtensions.GetInstance(TAsn1Sequence.GetInstance(LBytes)).Equivalent(LExts),
293+
'encoded round-trip');
294+
end;
295+
296+
procedure TX509ExtensionsTest.TestExtensionsGeneratorIExtension;
297+
var
298+
LExtGen: IX509ExtensionsGenerator;
299+
LExtension: IExtension;
300+
LExts: IX509Extensions;
301+
LReplacement: IExtension;
302+
begin
303+
LExtension := TExtension.Create(FOid1, TDerBoolean.False,
304+
TDerOctetString.FromContents([$05]));
305+
LExtGen := TX509ExtensionsGenerator.Create();
306+
LExtGen.AddExtension(LExtension);
307+
LExts := LExtGen.Generate();
308+
CheckNotNull(LExts.GetExtension(FOid1), 'added via IExtension');
309+
310+
LReplacement := TExtension.Create(FOid1, TDerBoolean.True,
311+
TDerOctetString.FromContents([$06]));
312+
LExtGen.ReplaceExtension(LReplacement);
313+
LExts := LExtGen.Generate();
314+
CheckTrue(LExts.GetExtension(FOid1).IsCritical, 'replaced critical flag');
315+
CheckTrue(TArrayUtilities.AreEqual(LExts.GetExtension(FOid1).Value.GetOctets(),
316+
LReplacement.ExtnValue.GetOctets()), 'replaced value');
317+
318+
LExtGen.Reset();
319+
LExtGen.AddExtensions(TExtensions.Create(LExtension) as IExtensions);
320+
LExts := LExtGen.Generate();
321+
CheckNotNull(LExts.GetExtension(FOid1), 'added via IExtensions');
322+
end;
323+
246324
initialization
247325

248326
{$IFDEF FPC}

CryptoLib/src/Asn1/X509/ClpX509Asn1Generators.pas

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,9 @@ TX509ExtensionsGenerator = class(TInterfacedObject, IX509ExtensionsGenerator)
197197
const AExtValue: TCryptoLibByteArray); overload;
198198
procedure AddExtension(const AOid: IDerObjectIdentifier;
199199
const AX509Extension: IX509Extension); overload;
200-
procedure AddExtensions(const AExtensions: IX509Extensions);
200+
procedure AddExtension(const AExtension: IExtension); overload;
201+
procedure AddExtensions(const AExtensions: IX509Extensions); overload;
202+
procedure AddExtensions(const AExtensions: IExtensions); overload;
201203
function Generate: IX509Extensions;
202204
function GetExtension(const AOid: IDerObjectIdentifier): IX509Extension;
203205
function HasExtension(const AOid: IDerObjectIdentifier): Boolean;
@@ -211,6 +213,7 @@ TX509ExtensionsGenerator = class(TInterfacedObject, IX509ExtensionsGenerator)
211213
const AExtValue: TCryptoLibByteArray); overload;
212214
procedure ReplaceExtension(const AOid: IDerObjectIdentifier;
213215
const AX509Extension: IX509Extension); overload;
216+
procedure ReplaceExtension(const AExtension: IExtension); overload;
214217
procedure Reset;
215218

216219
end;
@@ -747,6 +750,11 @@ procedure TX509ExtensionsGenerator.AddExtension(const AOid: IDerObjectIdentifier
747750
ImplAddExtension(AOid, AX509Extension);
748751
end;
749752

753+
procedure TX509ExtensionsGenerator.AddExtension(const AExtension: IExtension);
754+
begin
755+
AddExtension(AExtension.ExtnID, AExtension.GetX509Extension);
756+
end;
757+
750758
procedure TX509ExtensionsGenerator.AddExtensions(const AExtensions: IX509Extensions);
751759
var
752760
LOid: IDerObjectIdentifier;
@@ -759,6 +767,18 @@ procedure TX509ExtensionsGenerator.AddExtensions(const AExtensions: IX509Extensi
759767
end;
760768
end;
761769

770+
procedure TX509ExtensionsGenerator.AddExtensions(const AExtensions: IExtensions);
771+
var
772+
LOid: IDerObjectIdentifier;
773+
LExt: IExtension;
774+
begin
775+
for LOid in AExtensions.ExtensionOids do
776+
begin
777+
LExt := AExtensions.GetExtension(LOid);
778+
AddExtension(LOid, LExt.Critical.IsTrue, LExt.ExtnValue.GetOctets());
779+
end;
780+
end;
781+
762782
function TX509ExtensionsGenerator.Generate: IX509Extensions;
763783
begin
764784
Result := TX509Extensions.Create(FOrdering, FExtensions);
@@ -814,6 +834,11 @@ procedure TX509ExtensionsGenerator.ReplaceExtension(const AOid: IDerObjectIdenti
814834
FExtensions[AOid] := AX509Extension;
815835
end;
816836

837+
procedure TX509ExtensionsGenerator.ReplaceExtension(const AExtension: IExtension);
838+
begin
839+
ReplaceExtension(AExtension.ExtnID, AExtension.GetX509Extension);
840+
end;
841+
817842
procedure TX509ExtensionsGenerator.Reset;
818843
begin
819844
FExtensions.Clear;

0 commit comments

Comments
 (0)