318575bb8e
git-svn-id: https://svn.code.sf.net/p/synalist/code/trunk@31 7c85be65-684b-0410-a082-b2ed4fbef004
391 lines
10 KiB
ObjectPascal
391 lines
10 KiB
ObjectPascal
{==============================================================================|
|
|
| Project : Delphree - Synapse | 001.003.000 |
|
|
|==============================================================================|
|
|
| Content: support for ASN.1 coding and decoding |
|
|
|==============================================================================|
|
|
| The contents of this file are subject to the Mozilla Public License Ver. 1.0 |
|
|
| (the "License"); you may not use this file except in compliance with the |
|
|
| License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ |
|
|
| |
|
|
| Software distributed under the License is distributed on an "AS IS" basis, |
|
|
| WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for |
|
|
| the specific language governing rights and limitations under the License. |
|
|
|==============================================================================|
|
|
| The Original Code is Synapse Delphi Library. |
|
|
|==============================================================================|
|
|
| The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
|
|
| Portions created by Lukas Gebauer are Copyright (c) 1999, 2000. |
|
|
| Portions created by Hernan Sanchez are Copyright (c) 2000. |
|
|
| All Rights Reserved. |
|
|
|==============================================================================|
|
|
| Contributor(s): |
|
|
| Hernan Sanchez (hernan.sanchez@iname.com) |
|
|
|==============================================================================|
|
|
| History: see HISTORY.HTM from distribution package |
|
|
| (Found at URL: http://www.ararat.cz/synapse/) |
|
|
|==============================================================================}
|
|
|
|
unit ASN1Util;
|
|
|
|
interface
|
|
|
|
uses
|
|
SysUtils;
|
|
|
|
const
|
|
ASN1_INT = $02;
|
|
ASN1_OCTSTR = $04;
|
|
ASN1_NULL = $05;
|
|
ASN1_OBJID = $06;
|
|
ASN1_SEQ = $30;
|
|
ASN1_IPADDR = $40;
|
|
ASN1_COUNTER = $41;
|
|
ASN1_GAUGE = $42;
|
|
ASN1_TIMETICKS = $43;
|
|
ASN1_OPAQUE = $44;
|
|
|
|
function ASNEncOIDitem(Value: integer): string;
|
|
function ASNDecOIDitem(var Start: integer; Buffer: string): integer;
|
|
function ASNEncLen(Len: integer): string;
|
|
function ASNDecLen(var Start: integer; Buffer: string): integer;
|
|
function ASNEncInt(Value: integer): string;
|
|
function ASNEncUInt(Value: integer): string;
|
|
function ASNObject(Data: string; ASNType: integer): string;
|
|
function ASNItem(var Start: integer; Buffer: string; var ValueType:integer): string;
|
|
Function MibToId(mib:string):string;
|
|
Function IdToMib(id:string):string;
|
|
Function IntMibToStr(int:string):string;
|
|
function IPToID(Host: string): string;
|
|
|
|
implementation
|
|
|
|
{==============================================================================}
|
|
{ASNEncOIDitem}
|
|
function ASNEncOIDitem(Value: integer): string;
|
|
var
|
|
x,xm:integer;
|
|
b:boolean;
|
|
begin
|
|
x:=value;
|
|
b:=false;
|
|
result:='';
|
|
repeat
|
|
xm:=x mod 128;
|
|
x:=x div 128;
|
|
if b then
|
|
xm:=xm or $80;
|
|
if x>0
|
|
then b:=true;
|
|
result:=char(xm)+result;
|
|
until x=0;
|
|
end;
|
|
|
|
{==============================================================================}
|
|
{ASNDecOIDitem}
|
|
function ASNDecOIDitem(var Start: integer; Buffer: string): integer;
|
|
var
|
|
x:integer;
|
|
b:boolean;
|
|
begin
|
|
result:=0;
|
|
repeat
|
|
result:=result*128;
|
|
x := Ord(Buffer[Start]);
|
|
inc(start);
|
|
b:=x>$7f;
|
|
x:=x and $7f;
|
|
result:=result+x;
|
|
if not b
|
|
then break;
|
|
until false
|
|
end;
|
|
|
|
{==============================================================================}
|
|
{ASNEncLen}
|
|
function ASNEncLen(Len: integer): string;
|
|
var
|
|
x, y: integer;
|
|
begin
|
|
if (len<$80)
|
|
then result:=char(len)
|
|
else
|
|
begin
|
|
x:=len;
|
|
result:='';
|
|
repeat
|
|
y:=x mod 256;
|
|
x:=x div 256;
|
|
result:=char(y)+result;
|
|
until x=0;
|
|
y:=length(result);
|
|
y:=y or $80;
|
|
result:=char(y)+result;
|
|
end;
|
|
end;
|
|
|
|
{==============================================================================}
|
|
{ASNDecLen}
|
|
function ASNDecLen(var Start: integer; Buffer: string): integer;
|
|
var
|
|
x,n: integer;
|
|
begin
|
|
x:=Ord(Buffer[Start]);
|
|
Inc(Start);
|
|
if (x<$80)
|
|
then Result:=x
|
|
else
|
|
begin
|
|
result:=0;
|
|
x:=x and $7f;
|
|
for n:=1 to x do
|
|
begin
|
|
result:=result*256;
|
|
x:=Ord(Buffer[Start]);
|
|
Inc(Start);
|
|
result:=result+x;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{==============================================================================}
|
|
{ASNEncInt}
|
|
function ASNEncInt(Value: integer): string;
|
|
var
|
|
x,y:cardinal;
|
|
neg:boolean;
|
|
begin
|
|
neg:=value<0;
|
|
x:=abs(Value);
|
|
if neg then
|
|
x:=not (x-1);
|
|
result:='';
|
|
repeat
|
|
y:=x mod 256;
|
|
x:=x div 256;
|
|
result:=char(y)+result;
|
|
until x=0;
|
|
if (not neg) and (result[1]>#$7F)
|
|
then result:=#0+result;
|
|
end;
|
|
|
|
{==============================================================================}
|
|
{ASNEncUInt}
|
|
function ASNEncUInt(Value: integer): string;
|
|
var
|
|
x,y:integer;
|
|
neg:boolean;
|
|
begin
|
|
neg:=value<0;
|
|
x:=Value;
|
|
if neg
|
|
then x:=x and $7FFFFFFF;
|
|
result:='';
|
|
repeat
|
|
y:=x mod 256;
|
|
x:=x div 256;
|
|
result:=char(y)+result;
|
|
until x=0;
|
|
if neg
|
|
then result[1]:=char(ord(result[1]) or $80);
|
|
end;
|
|
|
|
{==============================================================================}
|
|
{ASNObject}
|
|
function ASNObject(Data: string; ASNType: integer): string;
|
|
begin
|
|
Result := Char(ASNType) + ASNEncLen(Length(Data)) + Data;
|
|
end;
|
|
|
|
{==============================================================================}
|
|
{ASNItem}
|
|
function ASNItem(var Start: integer; Buffer: string; var ValueType:integer): string;
|
|
var
|
|
ASNType: integer;
|
|
ASNSize: integer;
|
|
y,n: integer;
|
|
x: byte;
|
|
s: string;
|
|
c: char;
|
|
neg: boolean;
|
|
begin
|
|
ASNType := Ord(Buffer[Start]);
|
|
Valuetype:=ASNType;
|
|
Inc(start);
|
|
ASNSize := ASNDecLen(Start, Buffer);
|
|
Result := '';
|
|
if ((ASNType and $20) > 0) then
|
|
begin
|
|
Result := '$' + IntToHex(ASNType, 2);
|
|
end
|
|
else
|
|
case ASNType of
|
|
ASN1_INT:
|
|
begin
|
|
y := 0;
|
|
neg:=false;
|
|
for n := 1 to ASNSize do
|
|
begin
|
|
x:=Ord(Buffer[Start]);
|
|
if (n=1) and (x>$7F)
|
|
then neg:=true;
|
|
if neg
|
|
then x:=not x;
|
|
y := y * 256 + x;
|
|
Inc(Start);
|
|
end;
|
|
if neg
|
|
then y:=-(y+1);
|
|
Result := IntToStr(y);
|
|
end;
|
|
ASN1_COUNTER, ASN1_GAUGE, ASN1_TIMETICKS:
|
|
begin
|
|
y := 0;
|
|
for n := 1 to ASNSize do
|
|
begin
|
|
y := y * 256 + Ord(Buffer[Start]);
|
|
Inc(Start);
|
|
end;
|
|
Result := IntToStr(y);
|
|
end;
|
|
ASN1_OCTSTR, ASN1_OPAQUE:
|
|
begin
|
|
for n := 1 to ASNSize do
|
|
begin
|
|
c := Char(Buffer[Start]);
|
|
Inc(Start);
|
|
s := s + c;
|
|
end;
|
|
Result := s;
|
|
end;
|
|
ASN1_OBJID:
|
|
begin
|
|
for n := 1 to ASNSize do
|
|
begin
|
|
c := Char(Buffer[Start]);
|
|
Inc(Start);
|
|
s := s + c;
|
|
end;
|
|
Result := IdToMib(s);
|
|
end;
|
|
ASN1_IPADDR:
|
|
begin
|
|
s := '';
|
|
for n := 1 to ASNSize do
|
|
begin
|
|
if (n <> 1) then
|
|
s := s + '.';
|
|
y := Ord(Buffer[Start]);
|
|
Inc(Start);
|
|
s := s + IntToStr(y);
|
|
end;
|
|
Result := s;
|
|
end;
|
|
else // NULL
|
|
begin
|
|
Result := '';
|
|
Inc(Start);
|
|
Start := Start + ASNSize;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{==============================================================================}
|
|
{MibToId}
|
|
function MibToId(mib:string):string;
|
|
var
|
|
x:integer;
|
|
|
|
Function walkInt(var s:string):integer;
|
|
var
|
|
x:integer;
|
|
t:string;
|
|
begin
|
|
x:=pos('.',s);
|
|
if x<1 then
|
|
begin
|
|
t:=s;
|
|
s:='';
|
|
end
|
|
else
|
|
begin
|
|
t:=copy(s,1,x-1);
|
|
s:=copy(s,x+1,length(s)-x);
|
|
end;
|
|
result:=StrToIntDef(t,0);
|
|
end;
|
|
begin
|
|
result:='';
|
|
x:=walkint(mib);
|
|
x:=x*40+walkint(mib);
|
|
result:=ASNEncOIDItem(x);
|
|
while mib<>'' do
|
|
begin
|
|
x:=walkint(mib);
|
|
result:=result+ASNEncOIDItem(x);
|
|
end;
|
|
end;
|
|
|
|
{==============================================================================}
|
|
{IdToMib}
|
|
Function IdToMib(id:string):string;
|
|
var
|
|
x,y,n:integer;
|
|
begin
|
|
result:='';
|
|
n:=1;
|
|
while length(id)+1>n do
|
|
begin
|
|
x:=ASNDecOIDItem(n,id);
|
|
if (n-1)=1 then
|
|
begin
|
|
y:=x div 40;
|
|
x:=x mod 40;
|
|
result:=IntTostr(y);
|
|
end;
|
|
result:=result+'.'+IntToStr(x);
|
|
end;
|
|
end;
|
|
|
|
{==============================================================================}
|
|
{IntMibToStr}
|
|
Function IntMibToStr(int:string):string;
|
|
Var
|
|
n,y:integer;
|
|
begin
|
|
y:=0;
|
|
for n:=1 to length(int)-1 do
|
|
y:=y*256+ord(int[n]);
|
|
result:=IntToStr(y);
|
|
end;
|
|
|
|
{==============================================================================}
|
|
{IPToID} //Hernan Sanchez
|
|
function IPToID(Host: string): string;
|
|
var
|
|
s, t: string;
|
|
i, x: integer;
|
|
begin
|
|
Result := '';
|
|
for x:= 1 to 3 do
|
|
begin
|
|
t := '';
|
|
s := StrScan(PChar(Host), '.');
|
|
t := Copy(Host, 1, (Length(Host) - Length(s)));
|
|
Delete(Host, 1, (Length(Host) - Length(s) + 1));
|
|
i := StrTointDef(t, 0);
|
|
Result := Result + Chr(i);
|
|
end;
|
|
i := StrTointDef(Host, 0);
|
|
Result := Result + Chr(i);
|
|
end;
|
|
|
|
{==============================================================================}
|
|
|
|
begin
|
|
exit;
|
|
asm
|
|
db 'Synapse ASN.1 library by Lukas Gebauer',0
|
|
end;
|
|
end.
|
|
|