From 727d606b45402e6812b975cc83ff5b9d0d8de1dd Mon Sep 17 00:00:00 2001 From: mattias Date: Sun, 1 May 2022 14:15:01 +0200 Subject: [PATCH] fcl-hash: added some asn write functions --- packages/fcl-hash/src/fpasn.pp | 143 +++++++++++++++++++++++++++++---- 1 file changed, 128 insertions(+), 15 deletions(-) diff --git a/packages/fcl-hash/src/fpasn.pp b/packages/fcl-hash/src/fpasn.pp index 70b586b271..c7129e48a6 100644 --- a/packages/fcl-hash/src/fpasn.pp +++ b/packages/fcl-hash/src/fpasn.pp @@ -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=$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