Friendica Communications Platform
(please note that this is a clone of the repository at github, issues are handled there)
https://friendi.ca
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
169 lines
3.8 KiB
169 lines
3.8 KiB
<?php |
|
//----------------------------------------------------------------------------- |
|
// ASNValue class by A.Oliinyk |
|
// contact@pumka.net |
|
//----------------------------------------------------------------------------- |
|
class ASNValue |
|
{ |
|
const TAG_INTEGER = 0x02; |
|
const TAG_BITSTRING = 0x03; |
|
const TAG_SEQUENCE = 0x30; |
|
|
|
public $Tag; |
|
public $Value; |
|
|
|
function __construct($Tag=0x00, $Value='') |
|
{ |
|
$this->Tag = $Tag; |
|
$this->Value = $Value; |
|
} |
|
|
|
function Encode() |
|
{ |
|
//Write type |
|
$result = chr($this->Tag); |
|
|
|
//Write size |
|
$size = strlen($this->Value); |
|
if ($size < 127) { |
|
//Write size as is |
|
$result .= chr($size); |
|
} |
|
else { |
|
//Prepare length sequence |
|
$sizeBuf = self::IntToBin($size); |
|
|
|
//Write length sequence |
|
$firstByte = 0x80 + strlen($sizeBuf); |
|
$result .= chr($firstByte) . $sizeBuf; |
|
} |
|
|
|
//Write value |
|
$result .= $this->Value; |
|
|
|
return $result; |
|
} |
|
|
|
function Decode(&$Buffer) |
|
{ |
|
//Read type |
|
$this->Tag = self::ReadByte($Buffer); |
|
|
|
//Read first byte |
|
$firstByte = self::ReadByte($Buffer); |
|
|
|
if ($firstByte < 127) { |
|
$size = $firstByte; |
|
} |
|
else if ($firstByte > 127) { |
|
$sizeLen = $firstByte - 0x80; |
|
//Read length sequence |
|
$size = self::BinToInt(self::ReadBytes($Buffer, $sizeLen)); |
|
} |
|
else { |
|
throw new Exception("Invalid ASN length value"); |
|
} |
|
|
|
$this->Value = self::ReadBytes($Buffer, $size); |
|
} |
|
|
|
protected static function ReadBytes(&$Buffer, $Length) |
|
{ |
|
$result = substr($Buffer, 0, $Length); |
|
$Buffer = substr($Buffer, $Length); |
|
|
|
return $result; |
|
} |
|
|
|
protected static function ReadByte(&$Buffer) |
|
{ |
|
return ord(self::ReadBytes($Buffer, 1)); |
|
} |
|
|
|
protected static function BinToInt($Bin) |
|
{ |
|
$len = strlen($Bin); |
|
$result = 0; |
|
for ($i=0; $i<$len; $i++) { |
|
$curByte = self::ReadByte($Bin); |
|
$result += $curByte << (($len-$i-1)*8); |
|
} |
|
|
|
return $result; |
|
} |
|
|
|
protected static function IntToBin($Int) |
|
{ |
|
$result = ''; |
|
do { |
|
$curByte = $Int % 256; |
|
$result .= chr($curByte); |
|
|
|
$Int = ($Int - $curByte) / 256; |
|
} while ($Int > 0); |
|
|
|
$result = strrev($result); |
|
|
|
return $result; |
|
} |
|
|
|
function SetIntBuffer($Value) |
|
{ |
|
if (strlen($Value) > 1) { |
|
$firstByte = ord($Value{0}); |
|
if ($firstByte & 0x80) { //first bit set |
|
$Value = chr(0x00) . $Value; |
|
} |
|
} |
|
|
|
$this->Value = $Value; |
|
} |
|
|
|
function GetIntBuffer() |
|
{ |
|
$result = $this->Value; |
|
if (ord($result{0}) == 0x00) { |
|
$result = substr($result, 1); |
|
} |
|
|
|
return $result; |
|
} |
|
|
|
function SetInt($Value) |
|
{ |
|
$Value = self::IntToBin($Value); |
|
|
|
$this->SetIntBuffer($Value); |
|
} |
|
|
|
function GetInt() |
|
{ |
|
$result = $this->GetIntBuffer(); |
|
$result = self::BinToInt($result); |
|
|
|
return $result; |
|
} |
|
|
|
function SetSequence($Values) |
|
{ |
|
$result = ''; |
|
foreach ($Values as $item) { |
|
$result .= $item->Encode(); |
|
} |
|
|
|
$this->Value = $result; |
|
} |
|
|
|
function GetSequence() |
|
{ |
|
$result = array(); |
|
$seq = $this->Value; |
|
while (strlen($seq)) { |
|
$val = new ASNValue(); |
|
$val->Decode($seq); |
|
$result[] = $val; |
|
} |
|
|
|
return $result; |
|
} |
|
}
|
|
|