]> git.mxchange.org Git - friendica.git/blob - library/ASNValue.class.php
Merge pull request #2185 from tobiasd/20151214-translations
[friendica.git] / library / ASNValue.class.php
1 <?php
2 //-----------------------------------------------------------------------------
3 // ASNValue class by A.Oliinyk
4 // contact@pumka.net
5 //-----------------------------------------------------------------------------
6 class ASNValue
7 {
8     const TAG_INTEGER   = 0x02;
9     const TAG_BITSTRING = 0x03;
10     const TAG_SEQUENCE  = 0x30;
11     
12     public $Tag;
13     public $Value;
14     
15     function __construct($Tag=0x00, $Value='')
16     {
17         $this->Tag = $Tag;
18         $this->Value = $Value;
19     }
20     
21     function Encode()
22     {   
23         //Write type
24         $result = chr($this->Tag);
25
26         //Write size
27         $size = strlen($this->Value);
28         if ($size < 127) {
29             //Write size as is
30             $result .= chr($size);
31         }
32         else {
33             //Prepare length sequence
34             $sizeBuf = self::IntToBin($size);
35
36             //Write length sequence
37             $firstByte = 0x80 + strlen($sizeBuf);
38             $result .= chr($firstByte) . $sizeBuf;
39         }
40
41         //Write value
42         $result .= $this->Value;
43         
44         return $result;
45     }
46     
47     function Decode(&$Buffer)
48     {   
49         //Read type
50         $this->Tag = self::ReadByte($Buffer);
51
52         //Read first byte
53         $firstByte = self::ReadByte($Buffer);  
54
55         if ($firstByte < 127) {
56             $size = $firstByte;
57         }
58         else if ($firstByte > 127) {
59             $sizeLen = $firstByte - 0x80;
60             //Read length sequence
61             $size = self::BinToInt(self::ReadBytes($Buffer, $sizeLen));
62         }
63         else {
64             throw new Exception("Invalid ASN length value");
65         }
66
67         $this->Value = self::ReadBytes($Buffer, $size);
68     }
69     
70     protected static function ReadBytes(&$Buffer, $Length)
71     {
72         $result = substr($Buffer, 0, $Length);
73         $Buffer = substr($Buffer, $Length);
74         
75         return $result;
76     }
77     
78     protected static function ReadByte(&$Buffer)
79     {      
80         return ord(self::ReadBytes($Buffer, 1));
81     }
82     
83     protected static function BinToInt($Bin)
84     {    
85         $len = strlen($Bin);
86         $result = 0;
87         for ($i=0; $i<$len; $i++) {
88             $curByte = self::ReadByte($Bin);
89             $result += $curByte << (($len-$i-1)*8);
90         }
91         
92         return $result;
93     }
94     
95     protected static function IntToBin($Int)
96     {
97         $result = '';
98         do {
99             $curByte = $Int % 256;
100             $result .= chr($curByte);
101
102             $Int = ($Int - $curByte) / 256;
103         } while ($Int > 0);
104
105         $result = strrev($result);
106         
107         return $result;
108     }
109     
110     function SetIntBuffer($Value)
111     {
112         if (strlen($Value) > 1) {
113             $firstByte = ord($Value{0});
114             if ($firstByte & 0x80) { //first bit set
115                 $Value = chr(0x00) . $Value;
116             }
117         }
118         
119         $this->Value = $Value;
120     }
121     
122     function GetIntBuffer()    
123     {        
124         $result = $this->Value;
125         if (ord($result{0}) == 0x00) {
126             $result = substr($result, 1);
127         }
128         
129         return $result;
130     }
131     
132     function SetInt($Value)
133     {
134         $Value = self::IntToBin($Value);
135         
136         $this->SetIntBuffer($Value);
137     }   
138     
139     function GetInt()
140     {
141         $result = $this->GetIntBuffer();
142         $result = self::BinToInt($result);
143         
144         return $result;
145     }
146     
147     function SetSequence($Values)
148     {
149         $result = '';
150         foreach ($Values as $item) {
151             $result .= $item->Encode();            
152         }   
153         
154         $this->Value = $result;
155     }   
156     
157     function GetSequence()
158     {
159         $result = array();
160         $seq = $this->Value;
161         while (strlen($seq)) {
162             $val = new ASNValue();
163             $val->Decode($seq);
164             $result[] = $val;
165         }  
166         
167         return $result;
168     }    
169 }