aboutsummaryrefslogtreecommitdiffstats
path: root/library/ASNValue.class.php
diff options
context:
space:
mode:
Diffstat (limited to 'library/ASNValue.class.php')
-rw-r--r--library/ASNValue.class.php169
1 files changed, 169 insertions, 0 deletions
diff --git a/library/ASNValue.class.php b/library/ASNValue.class.php
new file mode 100644
index 000000000..7a3c5d20e
--- /dev/null
+++ b/library/ASNValue.class.php
@@ -0,0 +1,169 @@
+<?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;
+ }
+}