fcl-hash: added some asn write functions

This commit is contained in:
mattias 2022-05-01 14:15:01 +02:00
parent ddfe51415b
commit 727d606b45

View File

@ -58,6 +58,16 @@ procedure ASNEncodeLen(const Len: Integer; var Buffer: TBytes);
function ASNReadLen(var Buffer: PByte; BufferEnd: PByte): Int32;
procedure ASNEncodeInt(Value: Int64; var Result: TBytes);
procedure ASNEncodeUInt(Value: Integer; var Result: TBytes);
procedure ASNWriteNull(s: TStream);
procedure ASNWriteInt(Value: Int64; s: TStream);
procedure ASNWriteBigInt(Value: TBytes; s: TStream);
procedure ASNWriteObjID(const ObjID: string; s: TStream);
function ASNWriteSequenceBegin(s: TMemoryStream): int64;
procedure ASNWriteSequenceEnd(SeqBegin: int64; s: TMemoryStream);
function ASNWriteBitStrBegin(s: TMemoryStream): int64;
procedure ASNWriteBitStrEnd(BitStrBegin: int64; s: TMemoryStream);
// Encodes ASN.1 object to binary form
procedure ASNObject(const Data: String; const ASNType: Integer; var Buffer: TBytes);
// Encodes an MIB OID String to binary form
@ -65,12 +75,12 @@ procedure MibToId(Mib: String; var Result: String);
// Decodes MIB OID from binary form to String form.
procedure IdToMib(const Id: String; var Result: String); overload;
function IdToMib(Buffer, BufferEnd: PByte): string; overload;
procedure ASNDebug(const Buffer: TBytes; var Output: TBytes);
procedure ASNDebugList(const Prefix: string; List: TStrings);
procedure ASNParse(const Buffer: TBytes; List: TStrings);
procedure ASNParse_GetItem(List: TStrings; Index: integer; out ASNType, ASNSize: integer);
function ASNParse_GetIntBytes(List: TStrings; ListIndex: integer; ID: int64): TBytes;
function ASNFetch(var Buffer: PByte; BufferEnd: PByte; Out ASNType, ASNSize: Int32): Boolean; overload;
function ASNFetchOID(var Buffer: PByte; BufferEnd: PByte; out OID: String): Boolean; overload;
@ -247,11 +257,115 @@ begin
Result:=Concat(Result,[Ord(S[y])]);
end;
Procedure AppendStringToBuffer(var Buffer: TBytes; const aString : String);
procedure ASNWriteNull(s: TStream);
begin
s.WriteByte(ASN1_NULL);
s.WriteByte(0);
end;
procedure ASNWriteInt(Value: Int64; s: TStream);
var
aBytes, aLen: TBytes;
begin
aBytes:=[];
ASNEncodeInt(Value,aBytes);
aLen:=[];
ASNEncodeLen(length(aBytes),aLen);
s.WriteByte(ASN1_INT);
s.Write(aLen[0],length(aLen));
s.Write(aBytes[0],length(aBytes));
end;
procedure ASNWriteBigInt(Value: TBytes; s: TStream);
var
EndIndex: SizeInt;
aLen: TBytes;
StartIndex: Integer;
begin
EndIndex:=length(Value);
if EndIndex=0 then
raise Exception.Create('20220501115642');
StartIndex:=0;
while (StartIndex<EndIndex) and (Value[StartIndex]=0) do
inc(StartIndex);
if StartIndex=EndIndex then
begin
ASNWriteInt(0,s);
exit;
end;
if Value[StartIndex]>=$80 then
dec(StartIndex);
aLen:=[];
ASNEncodeLen(EndIndex-StartIndex,aLen);
s.WriteByte(ASN1_INT);
s.Write(aLen[0],length(aLen));
if StartIndex<0 then
begin
s.WriteByte(0);
StartIndex:=0;
end;
s.Write(Value[StartIndex],EndIndex-StartIndex);
end;
procedure ASNWriteObjID(const ObjID: string; s: TStream);
var
Mib: string;
aLen: TBytes;
begin
Mib:='';
MibToId(ObjID,Mib);
aLen:=[];
ASNEncodeLen(length(Mib),aLen);
s.WriteByte(ASN1_OBJID);
s.Write(aLen[0],length(aLen));
s.Write(Mib[1],length(Mib));
end;
function ASNWriteSequenceBegin(s: TMemoryStream): int64;
begin
s.WriteByte(ASN1_SEQ);
s.WriteByte(0);
Result:=s.Position;
end;
procedure ASNWriteSequenceEnd(SeqBegin: int64; s: TMemoryStream);
var
SeqLen: Int64;
aLen: TBytes;
l: SizeInt;
p: PByte;
begin
SeqLen:=s.Position-SeqBegin;
aLen:=[];
ASNEncodeLen(SeqLen,aLen);
l:=length(aLen);
if l>1 then
begin
s.Write(aLen[1],l-1);
p:=PByte(s.Memory);
System.Move(p[SeqBegin],p[SeqBegin+l-1],SeqLen);
System.Move(aLen[0],p[SeqBegin-1],l);
end else
PByte(s.Memory)[SeqBegin-1]:=aLen[0];
end;
function ASNWriteBitStrBegin(s: TMemoryStream): int64;
begin
s.WriteByte(ASN1_BITSTR);
s.WriteByte(0); // length
Result:=s.Position;
s.WriteByte(0); // trailing bit length
end;
procedure ASNWriteBitStrEnd(BitStrBegin: int64; s: TMemoryStream);
begin
ASNWriteSequenceEnd(BitStrBegin,s);
end;
Procedure AppendStringToBuffer(var Buffer: TBytes; const aString : String);
Var
Buflen,sLen : integer;
begin
bufLen:=Length(Buffer);
sLen:=Length(aString);
@ -261,8 +375,6 @@ begin
end;
procedure ASNObject(const Data: String; const ASNType: Integer; var Buffer: TBytes);
begin
Buffer:=Concat(Buffer,[ASNType]);
ASNEncodeLen(Length(Data), Buffer);
@ -304,19 +416,17 @@ begin
end;
end;
// @Result[256]
procedure MibToId(Mib: String; var Result: String);
function WalkInt(var S: String): Integer;
var
P : Integer;
begin
P:=Pos('.',S);
If P=0 then
P:=Length(S)+1;
Result:=StrToIntDef(Copy(S,1,P-1),0);
S:=Copy(S,Pos('.',S)+1,Length(S));
S:=Copy(S,P+1,Length(S));
end;
var
@ -332,7 +442,6 @@ begin
end;
end;
// @Result[256]
procedure IdToMib(const Id: String; var Result: String);
var
x, y, Index: Integer;
@ -455,7 +564,9 @@ begin
begin
BufToString(S);
if S[1] = Char(#00) then
begin
Delete(S,1,1);
end;
AppendStringToBuffer(Output, '$');
OutputHexa(Output, S);
end;
@ -498,7 +609,7 @@ begin
end;
ASN1_BITSTR:
begin
AppendStringToBuffer(Output, ' BITSTR: ');
AppendStringToBuffer(Output, ' BITSTR: len='+IntToStr(ASNSize)+' TrailBits='+IntToStr(Ord(Buffer^))+' ');
Inc(Buffer); // this is the Trailing Length in bits
Dec(ASNSize);
OldBuffer:=Buffer;
@ -584,21 +695,23 @@ var
ASNSize, ASNType, n: Integer;
Indent: Integer;
IndentList: Array of Integer;
p, EndP: PByte;
StartP, p, EndP: PByte;
begin
if length(Buffer)=0 then exit;
IndentList:=[];
Indent:=0;
p:=@Buffer[0];
EndP:=p+length(Buffer);
StartP:=@Buffer[0];
p:=StartP;
EndP:=StartP+length(Buffer);
while p<EndP do
begin
//writeln('ASNDebug p=',p-StartP,' Type=',hexstr(p^,2),' Indent=',length(IndentList));
// check if any sequence/set has ended and unindent
for n := Length(IndentList)-1 downto 0 do
begin
ASNSize := IndentList[n];
if EndP-p >= ASNSize then
if p-StartP >= ASNSize then
begin
Delete(IndentList,n,1);
Dec(Indent, 2);
@ -610,7 +723,7 @@ begin
begin
// sequence/set -> indent
Inc(Indent, 2);
IndentList:=Concat(IndentList,[ASNSize+integer(EndP-p)]);
IndentList:=Concat(IndentList,[ASNSize+integer(p-StartP)]);
end;
AppendStringToBuffer(Output, #13#10);
end;