home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 December / Chip_2001-12_cd1.bin / zkuste / delphi / unity / d23456 / SYNAPSE.ZIP / source / lib / ASN1Util.pas next >
Encoding:
Pascal/Delphi Source File  |  2001-09-23  |  9.6 KB  |  361 lines

  1. {==============================================================================|
  2. | Project : Delphree - Synapse                                   | 001.003.004 |
  3. |==============================================================================|
  4. | Content: support for ASN.1 coding and decoding                               |
  5. |==============================================================================|
  6. | The contents of this file are subject to the Mozilla Public License Ver. 1.1 |
  7. | (the "License"); you may not use this file except in compliance with the     |
  8. | License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ |
  9. |                                                                              |
  10. | Software distributed under the License is distributed on an "AS IS" basis,   |
  11. | WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for |
  12. | the specific language governing rights and limitations under the License.    |
  13. |==============================================================================|
  14. | The Original Code is Synapse Delphi Library.                                 |
  15. |==============================================================================|
  16. | The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
  17. | Portions created by Lukas Gebauer are Copyright (c) 1999,2000,2001.          |
  18. | Portions created by Hernan Sanchez are Copyright (c) 2000.                   |
  19. | All Rights Reserved.                                                         |
  20. |==============================================================================|
  21. | Contributor(s):                                                              |
  22. |   Hernan Sanchez (hernan.sanchez@iname.com)                                  |
  23. |==============================================================================|
  24. | History: see HISTORY.HTM from distribution package                           |
  25. |          (Found at URL: http://www.ararat.cz/synapse/)                       |
  26. |==============================================================================}
  27.  
  28. {$Q-}
  29. {$WEAKPACKAGEUNIT ON}
  30.  
  31. unit ASN1Util;
  32.  
  33. interface
  34.  
  35. uses
  36.   SysUtils;
  37.  
  38. const
  39.   ASN1_INT = $02;
  40.   ASN1_OCTSTR = $04;
  41.   ASN1_NULL = $05;
  42.   ASN1_OBJID = $06;
  43.   ASN1_SEQ = $30;
  44.   ASN1_IPADDR = $40;
  45.   ASN1_COUNTER = $41;
  46.   ASN1_GAUGE = $42;
  47.   ASN1_TIMETICKS = $43;
  48.   ASN1_OPAQUE = $44;
  49.  
  50. function ASNEncOIDItem(Value: Integer): string;
  51. function ASNDecOIDItem(var Start: Integer; const Buffer: string): Integer;
  52. function ASNEncLen(Len: Integer): string;
  53. function ASNDecLen(var Start: Integer; const Buffer: string): Integer;
  54. function ASNEncInt(Value: Integer): string;
  55. function ASNEncUInt(Value: Integer): string;
  56. function ASNObject(const Data: string; ASNType: Integer): string;
  57. function ASNItem(var Start: Integer; const Buffer: string;
  58.   var ValueType: Integer): string;
  59. function MibToId(Mib: string): string;
  60. function IdToMib(const Id: string): string;
  61. function IntMibToStr(const Value: string): string;
  62.  
  63. implementation
  64.  
  65. {==============================================================================}
  66. function ASNEncOIDItem(Value: Integer): string;
  67. var
  68.   x, xm: Integer;
  69.   b: Boolean;
  70. begin
  71.   x := Value;
  72.   b := False;
  73.   Result := '';
  74.   repeat
  75.     xm := x mod 128;
  76.     x := x div 128;
  77.     if b then
  78.       xm := xm or $80;
  79.     if x > 0 then
  80.       b := True;
  81.     Result := Char(xm) + Result;
  82.   until x = 0;
  83. end;
  84.  
  85. {==============================================================================}
  86. function ASNDecOIDItem(var Start: Integer; const Buffer: string): Integer;
  87. var
  88.   x: Integer;
  89.   b: Boolean;
  90. begin
  91.   Result := 0;
  92.   repeat
  93.     Result := Result * 128;
  94.     x := Ord(Buffer[Start]);
  95.     Inc(Start);
  96.     b := x > $7F;
  97.     x := x and $7F;
  98.     Result := Result + x;
  99.   until not b;
  100. end;
  101.  
  102. {==============================================================================}
  103. function ASNEncLen(Len: Integer): string;
  104. var
  105.   x, y: Integer;
  106. begin
  107.   if Len < $80 then
  108.     Result := Char(Len)
  109.   else
  110.   begin
  111.     x := Len;
  112.     Result := '';
  113.     repeat
  114.       y := x mod 256;
  115.       x := x div 256;
  116.       Result := Char(y) + Result;
  117.     until x = 0;
  118.     y := Length(Result);
  119.     y := y or $80;
  120.     Result := Char(y) + Result;
  121.   end;
  122. end;
  123.  
  124. {==============================================================================}
  125. function ASNDecLen(var Start: Integer; const Buffer: string): Integer;
  126. var
  127.   x, n: Integer;
  128. begin
  129.   x := Ord(Buffer[Start]);
  130.   Inc(Start);
  131.   if x < $80 then
  132.     Result := x
  133.   else
  134.   begin
  135.     Result := 0;
  136.     x := x and $7F;
  137.     for n := 1 to x do
  138.     begin
  139.       Result := Result * 256;
  140.       x := Ord(Buffer[Start]);
  141.       Inc(Start);
  142.       Result := Result + x;
  143.     end;
  144.   end;
  145. end;
  146.  
  147. {==============================================================================}
  148. function ASNEncInt(Value: Integer): string;
  149. var
  150.   x, y: Cardinal;
  151.   neg: Boolean;
  152. begin
  153.   neg := Value < 0;
  154.   x := Abs(Value);
  155.   if neg then
  156.     x := not (x - 1);
  157.   Result := '';
  158.   repeat
  159.     y := x mod 256;
  160.     x := x div 256;
  161.     Result := Char(y) + Result;
  162.   until x = 0;
  163.   if (not neg) and (Result[1] > #$7F) then
  164.     Result := #0 + Result;
  165. end;
  166.  
  167. {==============================================================================}
  168. function ASNEncUInt(Value: Integer): string;
  169. var
  170.   x, y: Integer;
  171.   neg: Boolean;
  172. begin
  173.   neg := Value < 0;
  174.   x := Value;
  175.   if neg then
  176.     x := x and $7FFFFFFF;
  177.   Result := '';
  178.   repeat
  179.     y := x mod 256;
  180.     x := x div 256;
  181.     Result := Char(y) + Result;
  182.   until x = 0;
  183.   if neg then
  184.     Result[1] := Char(Ord(Result[1]) or $80);
  185. end;
  186.  
  187. {==============================================================================}
  188. function ASNObject(const Data: string; ASNType: Integer): string;
  189. begin
  190.   Result := Char(ASNType) + ASNEncLen(Length(Data)) + Data;
  191. end;
  192.  
  193. {==============================================================================}
  194. function ASNItem(var Start: Integer; const Buffer: string;
  195.   var ValueType: Integer): string;
  196. var
  197.   ASNType: Integer;
  198.   ASNSize: Integer;
  199.   y, n: Integer;
  200.   x: byte;
  201.   s: string;
  202.   c: char;
  203.   neg: Boolean;
  204.   l: Integer;
  205. begin
  206.   Result := '';
  207.   ValueType := ASN1_NULL;
  208.   l := Length(Buffer);
  209.   if l < (Start + 1) then
  210.     Exit;
  211.   ASNType := Ord(Buffer[Start]);
  212.   ValueType := ASNType;
  213.   Inc(Start);
  214.   ASNSize := ASNDecLen(Start, Buffer);
  215.   if (Start + ASNSize - 1) > l then
  216.     Exit;
  217.   if (ASNType and $20) > 0 then
  218.     Result := '$' + IntToHex(ASNType, 2)
  219.   else
  220.     case ASNType of
  221.       ASN1_INT:
  222.         begin
  223.           y := 0;
  224.           neg := False;
  225.           for n := 1 to ASNSize do
  226.           begin
  227.             x := Ord(Buffer[Start]);
  228.             if (n = 1) and (x > $7F) then
  229.               neg := True;
  230.             if neg then
  231.               x := not x;
  232.             y := y * 256 + x;
  233.             Inc(Start);
  234.           end;
  235.           if neg then
  236.             y := -(y + 1);
  237.           Result := IntToStr(y);
  238.         end;
  239.       ASN1_COUNTER, ASN1_GAUGE, ASN1_TIMETICKS:
  240.         begin
  241.           y := 0;
  242.           for n := 1 to ASNSize do
  243.           begin
  244.             y := y * 256 + Ord(Buffer[Start]);
  245.             Inc(Start);
  246.           end;
  247.           Result := IntToStr(y);
  248.         end;
  249.       ASN1_OCTSTR, ASN1_OPAQUE:
  250.         begin
  251.           for n := 1 to ASNSize do
  252.           begin
  253.             c := Char(Buffer[Start]);
  254.             Inc(Start);
  255.             s := s + c;
  256.           end;
  257.           Result := s;
  258.         end;
  259.       ASN1_OBJID:
  260.         begin
  261.           for n := 1 to ASNSize do
  262.           begin
  263.             c := Char(Buffer[Start]);
  264.             Inc(Start);
  265.             s := s + c;
  266.           end;
  267.           Result := IdToMib(s);
  268.         end;
  269.       ASN1_IPADDR:
  270.         begin
  271.           s := '';
  272.           for n := 1 to ASNSize do
  273.           begin
  274.             if (n <> 1) then
  275.               s := s + '.';
  276.             y := Ord(Buffer[Start]);
  277.             Inc(Start);
  278.             s := s + IntToStr(y);
  279.           end;
  280.           Result := s;
  281.         end;
  282.     else // NULL
  283.       begin
  284.         Result := '';
  285.         Inc(Start);
  286.         Start := Start + ASNSize;
  287.       end;
  288.     end;
  289. end;
  290.  
  291. {==============================================================================}
  292. function MibToId(Mib: string): string;
  293. var
  294.   x: Integer;
  295.  
  296.   function WalkInt(var s: string): Integer;
  297.   var
  298.     x: Integer;
  299.     t: string;
  300.   begin
  301.     x := Pos('.', s);
  302.     if x < 1 then
  303.     begin
  304.       t := s;
  305.       s := '';
  306.     end
  307.     else
  308.     begin
  309.       t := Copy(s, 1, x - 1);
  310.       s := Copy(s, x + 1, Length(s) - x);
  311.     end;
  312.     Result := StrToIntDef(t, 0);
  313.   end;
  314.  
  315. begin
  316.   Result := '';
  317.   x := WalkInt(Mib);
  318.   x := x * 40 + WalkInt(Mib);
  319.   Result := ASNEncOIDItem(x);
  320.   while Mib <> '' do
  321.   begin
  322.     x := WalkInt(Mib);
  323.     Result := Result + ASNEncOIDItem(x);
  324.   end;
  325. end;
  326.  
  327. {==============================================================================}
  328. function IdToMib(const Id: string): string;
  329. var
  330.   x, y, n: Integer;
  331. begin
  332.   Result := '';
  333.   n := 1;
  334.   while Length(Id) + 1 > n do
  335.   begin
  336.     x := ASNDecOIDItem(n, Id);
  337.     if (n - 1) = 1 then
  338.     begin
  339.       y := x div 40;
  340.       x := x mod 40;
  341.       Result := IntToStr(y);
  342.     end;
  343.     Result := Result + '.' + IntToStr(x);
  344.   end;
  345. end;
  346.  
  347. {==============================================================================}
  348. function IntMibToStr(const Value: string): string;
  349. var
  350.   n, y: Integer;
  351. begin
  352.   y := 0;
  353.   for n := 1 to Length(Value) - 1 do
  354.     y := y * 256 + Ord(Value[n]);
  355.   Result := IntToStr(y);
  356. end;
  357.  
  358. {==============================================================================}
  359.  
  360. end.
  361.