home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 November / Chip_2002-11_cd1.bin / zkuste / delphi / kompon / d3456 / SYNAPSE.ZIP / source / lib / ASN1Util.pas next >
Pascal/Delphi Source File  |  2002-07-07  |  11KB  |  380 lines

  1. {==============================================================================|
  2. | Project : Delphree - Synapse                                   | 001.003.004 |
  3. |==============================================================================|
  4. | Content: support for ASN.1 BER coding and decoding                           |
  5. |==============================================================================|
  6. | Copyright (c)1999-2002, Lukas Gebauer                                        |
  7. | All rights reserved.                                                         |
  8. |                                                                              |
  9. | Redistribution and use in source and binary forms, with or without           |
  10. | modification, are permitted provided that the following conditions are met:  |
  11. |                                                                              |
  12. | Redistributions of source code must retain the above copyright notice, this  |
  13. | list of conditions and the following disclaimer.                             |
  14. |                                                                              |
  15. | Redistributions in binary form must reproduce the above copyright notice,    |
  16. | this list of conditions and the following disclaimer in the documentation    |
  17. | and/or other materials provided with the distribution.                       |
  18. |                                                                              |
  19. | Neither the name of Lukas Gebauer nor the names of its contributors may      |
  20. | be used to endorse or promote products derived from this software without    |
  21. | specific prior written permission.                                           |
  22. |                                                                              |
  23. | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"  |
  24. | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE    |
  25. | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE   |
  26. | ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR  |
  27. | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL       |
  28. | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR   |
  29. | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER   |
  30. | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT           |
  31. | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY    |
  32. | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH  |
  33. | DAMAGE.                                                                      |
  34. |==============================================================================|
  35. | The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
  36. | Portions created by Lukas Gebauer are Copyright (c) 1999,2000,2001.          |
  37. | Portions created by Hernan Sanchez are Copyright (c) 2000.                   |
  38. | All Rights Reserved.                                                         |
  39. |==============================================================================|
  40. | Contributor(s):                                                              |
  41. |   Hernan Sanchez (hernan.sanchez@iname.com)                                  |
  42. |==============================================================================|
  43. | History: see HISTORY.HTM from distribution package                           |
  44. |          (Found at URL: http://www.ararat.cz/synapse/)                       |
  45. |==============================================================================}
  46.  
  47. {$Q-}
  48. {$WEAKPACKAGEUNIT ON}
  49.  
  50. unit ASN1Util;
  51.  
  52. interface
  53.  
  54. uses
  55.   SysUtils;
  56.  
  57. const
  58.   ASN1_INT = $02;
  59.   ASN1_OCTSTR = $04;
  60.   ASN1_NULL = $05;
  61.   ASN1_OBJID = $06;
  62.   ASN1_SEQ = $30;
  63.   ASN1_IPADDR = $40;
  64.   ASN1_COUNTER = $41;
  65.   ASN1_GAUGE = $42;
  66.   ASN1_TIMETICKS = $43;
  67.   ASN1_OPAQUE = $44;
  68.  
  69. function ASNEncOIDItem(Value: Integer): string;
  70. function ASNDecOIDItem(var Start: Integer; const Buffer: string): Integer;
  71. function ASNEncLen(Len: Integer): string;
  72. function ASNDecLen(var Start: Integer; const Buffer: string): Integer;
  73. function ASNEncInt(Value: Integer): string;
  74. function ASNEncUInt(Value: Integer): string;
  75. function ASNObject(const Data: string; ASNType: Integer): string;
  76. function ASNItem(var Start: Integer; const Buffer: string;
  77.   var ValueType: Integer): string;
  78. function MibToId(Mib: string): string;
  79. function IdToMib(const Id: string): string;
  80. function IntMibToStr(const Value: string): string;
  81.  
  82. implementation
  83.  
  84. {==============================================================================}
  85. function ASNEncOIDItem(Value: Integer): string;
  86. var
  87.   x, xm: Integer;
  88.   b: Boolean;
  89. begin
  90.   x := Value;
  91.   b := False;
  92.   Result := '';
  93.   repeat
  94.     xm := x mod 128;
  95.     x := x div 128;
  96.     if b then
  97.       xm := xm or $80;
  98.     if x > 0 then
  99.       b := True;
  100.     Result := Char(xm) + Result;
  101.   until x = 0;
  102. end;
  103.  
  104. {==============================================================================}
  105. function ASNDecOIDItem(var Start: Integer; const Buffer: string): Integer;
  106. var
  107.   x: Integer;
  108.   b: Boolean;
  109. begin
  110.   Result := 0;
  111.   repeat
  112.     Result := Result * 128;
  113.     x := Ord(Buffer[Start]);
  114.     Inc(Start);
  115.     b := x > $7F;
  116.     x := x and $7F;
  117.     Result := Result + x;
  118.   until not b;
  119. end;
  120.  
  121. {==============================================================================}
  122. function ASNEncLen(Len: Integer): string;
  123. var
  124.   x, y: Integer;
  125. begin
  126.   if Len < $80 then
  127.     Result := Char(Len)
  128.   else
  129.   begin
  130.     x := Len;
  131.     Result := '';
  132.     repeat
  133.       y := x mod 256;
  134.       x := x div 256;
  135.       Result := Char(y) + Result;
  136.     until x = 0;
  137.     y := Length(Result);
  138.     y := y or $80;
  139.     Result := Char(y) + Result;
  140.   end;
  141. end;
  142.  
  143. {==============================================================================}
  144. function ASNDecLen(var Start: Integer; const Buffer: string): Integer;
  145. var
  146.   x, n: Integer;
  147. begin
  148.   x := Ord(Buffer[Start]);
  149.   Inc(Start);
  150.   if x < $80 then
  151.     Result := x
  152.   else
  153.   begin
  154.     Result := 0;
  155.     x := x and $7F;
  156.     for n := 1 to x do
  157.     begin
  158.       Result := Result * 256;
  159.       x := Ord(Buffer[Start]);
  160.       Inc(Start);
  161.       Result := Result + x;
  162.     end;
  163.   end;
  164. end;
  165.  
  166. {==============================================================================}
  167. function ASNEncInt(Value: Integer): string;
  168. var
  169.   x, y: Cardinal;
  170.   neg: Boolean;
  171. begin
  172.   neg := Value < 0;
  173.   x := Abs(Value);
  174.   if neg then
  175.     x := not (x - 1);
  176.   Result := '';
  177.   repeat
  178.     y := x mod 256;
  179.     x := x div 256;
  180.     Result := Char(y) + Result;
  181.   until x = 0;
  182.   if (not neg) and (Result[1] > #$7F) then
  183.     Result := #0 + Result;
  184. end;
  185.  
  186. {==============================================================================}
  187. function ASNEncUInt(Value: Integer): string;
  188. var
  189.   x, y: Integer;
  190.   neg: Boolean;
  191. begin
  192.   neg := Value < 0;
  193.   x := Value;
  194.   if neg then
  195.     x := x and $7FFFFFFF;
  196.   Result := '';
  197.   repeat
  198.     y := x mod 256;
  199.     x := x div 256;
  200.     Result := Char(y) + Result;
  201.   until x = 0;
  202.   if neg then
  203.     Result[1] := Char(Ord(Result[1]) or $80);
  204. end;
  205.  
  206. {==============================================================================}
  207. function ASNObject(const Data: string; ASNType: Integer): string;
  208. begin
  209.   Result := Char(ASNType) + ASNEncLen(Length(Data)) + Data;
  210. end;
  211.  
  212. {==============================================================================}
  213. function ASNItem(var Start: Integer; const Buffer: string;
  214.   var ValueType: Integer): string;
  215. var
  216.   ASNType: Integer;
  217.   ASNSize: Integer;
  218.   y, n: Integer;
  219.   x: byte;
  220.   s: string;
  221.   c: char;
  222.   neg: Boolean;
  223.   l: Integer;
  224. begin
  225.   Result := '';
  226.   ValueType := ASN1_NULL;
  227.   l := Length(Buffer);
  228.   if l < (Start + 1) then
  229.     Exit;
  230.   ASNType := Ord(Buffer[Start]);
  231.   ValueType := ASNType;
  232.   Inc(Start);
  233.   ASNSize := ASNDecLen(Start, Buffer);
  234.   if (Start + ASNSize - 1) > l then
  235.     Exit;
  236.   if (ASNType and $20) > 0 then
  237.     Result := '$' + IntToHex(ASNType, 2)
  238.   else
  239.     case ASNType of
  240.       ASN1_INT:
  241.         begin
  242.           y := 0;
  243.           neg := False;
  244.           for n := 1 to ASNSize do
  245.           begin
  246.             x := Ord(Buffer[Start]);
  247.             if (n = 1) and (x > $7F) then
  248.               neg := True;
  249.             if neg then
  250.               x := not x;
  251.             y := y * 256 + x;
  252.             Inc(Start);
  253.           end;
  254.           if neg then
  255.             y := -(y + 1);
  256.           Result := IntToStr(y);
  257.         end;
  258.       ASN1_COUNTER, ASN1_GAUGE, ASN1_TIMETICKS:
  259.         begin
  260.           y := 0;
  261.           for n := 1 to ASNSize do
  262.           begin
  263.             y := y * 256 + Ord(Buffer[Start]);
  264.             Inc(Start);
  265.           end;
  266.           Result := IntToStr(y);
  267.         end;
  268.       ASN1_OCTSTR, ASN1_OPAQUE:
  269.         begin
  270.           for n := 1 to ASNSize do
  271.           begin
  272.             c := Char(Buffer[Start]);
  273.             Inc(Start);
  274.             s := s + c;
  275.           end;
  276.           Result := s;
  277.         end;
  278.       ASN1_OBJID:
  279.         begin
  280.           for n := 1 to ASNSize do
  281.           begin
  282.             c := Char(Buffer[Start]);
  283.             Inc(Start);
  284.             s := s + c;
  285.           end;
  286.           Result := IdToMib(s);
  287.         end;
  288.       ASN1_IPADDR:
  289.         begin
  290.           s := '';
  291.           for n := 1 to ASNSize do
  292.           begin
  293.             if (n <> 1) then
  294.               s := s + '.';
  295.             y := Ord(Buffer[Start]);
  296.             Inc(Start);
  297.             s := s + IntToStr(y);
  298.           end;
  299.           Result := s;
  300.         end;
  301.     else // NULL
  302.       begin
  303.         Result := '';
  304.         Inc(Start);
  305.         Start := Start + ASNSize;
  306.       end;
  307.     end;
  308. end;
  309.  
  310. {==============================================================================}
  311. function MibToId(Mib: string): string;
  312. var
  313.   x: Integer;
  314.  
  315.   function WalkInt(var s: string): Integer;
  316.   var
  317.     x: Integer;
  318.     t: string;
  319.   begin
  320.     x := Pos('.', s);
  321.     if x < 1 then
  322.     begin
  323.       t := s;
  324.       s := '';
  325.     end
  326.     else
  327.     begin
  328.       t := Copy(s, 1, x - 1);
  329.       s := Copy(s, x + 1, Length(s) - x);
  330.     end;
  331.     Result := StrToIntDef(t, 0);
  332.   end;
  333.  
  334. begin
  335.   Result := '';
  336.   x := WalkInt(Mib);
  337.   x := x * 40 + WalkInt(Mib);
  338.   Result := ASNEncOIDItem(x);
  339.   while Mib <> '' do
  340.   begin
  341.     x := WalkInt(Mib);
  342.     Result := Result + ASNEncOIDItem(x);
  343.   end;
  344. end;
  345.  
  346. {==============================================================================}
  347. function IdToMib(const Id: string): string;
  348. var
  349.   x, y, n: Integer;
  350. begin
  351.   Result := '';
  352.   n := 1;
  353.   while Length(Id) + 1 > n do
  354.   begin
  355.     x := ASNDecOIDItem(n, Id);
  356.     if (n - 1) = 1 then
  357.     begin
  358.       y := x div 40;
  359.       x := x mod 40;
  360.       Result := IntToStr(y);
  361.     end;
  362.     Result := Result + '.' + IntToStr(x);
  363.   end;
  364. end;
  365.  
  366. {==============================================================================}
  367. function IntMibToStr(const Value: string): string;
  368. var
  369.   n, y: Integer;
  370. begin
  371.   y := 0;
  372.   for n := 1 to Length(Value) - 1 do
  373.     y := y * 256 + Ord(Value[n]);
  374.   Result := IntToStr(y);
  375. end;
  376.  
  377. {==============================================================================}
  378.  
  379. end.
  380.