2 //-----------------------------------------------------------------------------
3 // ASNValue class by A.Oliinyk
5 //-----------------------------------------------------------------------------
8 const TAG_INTEGER = 0x02;
9 const TAG_BITSTRING = 0x03;
10 const TAG_SEQUENCE = 0x30;
15 function __construct($Tag=0x00, $Value='')
18 $this->Value = $Value;
24 $result = chr($this->Tag);
27 $size = strlen($this->Value);
30 $result .= chr($size);
33 //Prepare length sequence
34 $sizeBuf = self::IntToBin($size);
36 //Write length sequence
37 $firstByte = 0x80 + strlen($sizeBuf);
38 $result .= chr($firstByte) . $sizeBuf;
42 $result .= $this->Value;
47 function Decode(&$Buffer)
50 $this->Tag = self::ReadByte($Buffer);
53 $firstByte = self::ReadByte($Buffer);
55 if ($firstByte < 127) {
58 else if ($firstByte > 127) {
59 $sizeLen = $firstByte - 0x80;
60 //Read length sequence
61 $size = self::BinToInt(self::ReadBytes($Buffer, $sizeLen));
64 throw new Exception("Invalid ASN length value");
67 $this->Value = self::ReadBytes($Buffer, $size);
70 protected static function ReadBytes(&$Buffer, $Length)
72 $result = substr($Buffer, 0, $Length);
73 $Buffer = substr($Buffer, $Length);
78 protected static function ReadByte(&$Buffer)
80 return ord(self::ReadBytes($Buffer, 1));
83 protected static function BinToInt($Bin)
87 for ($i=0; $i<$len; $i++) {
88 $curByte = self::ReadByte($Bin);
89 $result += $curByte << (($len-$i-1)*8);
95 protected static function IntToBin($Int)
99 $curByte = $Int % 256;
100 $result .= chr($curByte);
102 $Int = ($Int - $curByte) / 256;
105 $result = strrev($result);
110 function SetIntBuffer($Value)
112 if (strlen($Value) > 1) {
113 $firstByte = ord($Value{0});
114 if ($firstByte & 0x80) { //first bit set
115 $Value = chr(0x00) . $Value;
119 $this->Value = $Value;
122 function GetIntBuffer()
124 $result = $this->Value;
125 if (ord($result{0}) == 0x00) {
126 $result = substr($result, 1);
132 function SetInt($Value)
134 $Value = self::IntToBin($Value);
136 $this->SetIntBuffer($Value);
141 $result = $this->GetIntBuffer();
142 $result = self::BinToInt($result);
147 function SetSequence($Values)
150 foreach ($Values as $item) {
151 $result .= $item->Encode();
154 $this->Value = $result;
157 function GetSequence()
161 while (strlen($seq)) {
162 $val = new ASNValue();