diff options
Diffstat (limited to 'library')
-rw-r--r-- | library/ASNValue.class.php | 169 | ||||
-rw-r--r-- | library/asn1.php | 291 |
2 files changed, 0 insertions, 460 deletions
diff --git a/library/ASNValue.class.php b/library/ASNValue.class.php deleted file mode 100644 index 7c17d10b4..000000000 --- a/library/ASNValue.class.php +++ /dev/null @@ -1,169 +0,0 @@ -<?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; - } -} diff --git a/library/asn1.php b/library/asn1.php deleted file mode 100644 index 6ab8c6210..000000000 --- a/library/asn1.php +++ /dev/null @@ -1,291 +0,0 @@ -<?php - -// ASN.1 parsing library -// Attribution: http://www.krisbailey.com -// license: unknown -// modified: Mike Macgrivin mike@macgirvin.com 6-oct-2010 to support Salmon auto-discovery -// from openssl public keys - - -class ASN_BASE { - public $asnData = null; - private $cursor = 0; - private $parent = null; - - public static $ASN_MARKERS = array( - 'ASN_UNIVERSAL' => 0x00, - 'ASN_APPLICATION' => 0x40, - 'ASN_CONTEXT' => 0x80, - 'ASN_PRIVATE' => 0xC0, - - 'ASN_PRIMITIVE' => 0x00, - 'ASN_CONSTRUCTOR' => 0x20, - - 'ASN_LONG_LEN' => 0x80, - 'ASN_EXTENSION_ID' => 0x1F, - 'ASN_BIT' => 0x80, - ); - - public static $ASN_TYPES = array( - 1 => 'ASN_BOOLEAN', - 2 => 'ASN_INTEGER', - 3 => 'ASN_BIT_STR', - 4 => 'ASN_OCTET_STR', - 5 => 'ASN_NULL', - 6 => 'ASN_OBJECT_ID', - 9 => 'ASN_REAL', - 10 => 'ASN_ENUMERATED', - 13 => 'ASN_RELATIVE_OID', - 48 => 'ASN_SEQUENCE', - 49 => 'ASN_SET', - 19 => 'ASN_PRINT_STR', - 22 => 'ASN_IA5_STR', - 23 => 'ASN_UTC_TIME', - 24 => 'ASN_GENERAL_TIME', - ); - - function __construct($v = false) - { - if (false !== $v) { - $this->asnData = $v; - if (is_array($this->asnData)) { - foreach ($this->asnData as $key => $value) { - if (is_object($value)) { - $this->asnData[$key]->setParent($this); - } - } - } else { - if (is_object($this->asnData)) { - $this->asnData->setParent($this); - } - } - } - } - - public function setParent($parent) - { - if (false !== $parent) { - $this->parent = $parent; - } - } - - /** - * This function will take the markers and types arrays and - * dynamically generate classes that extend this class for each one, - * and also define constants for them. - */ - public static function generateSubclasses() - { - define('ASN_BASE', 0); - foreach (self::$ASN_MARKERS as $name => $bit) - self::makeSubclass($name, $bit); - foreach (self::$ASN_TYPES as $bit => $name) - self::makeSubclass($name, $bit); - } - - /** - * Helper function for generateSubclasses() - */ - public static function makeSubclass($name, $bit) - { - define($name, $bit); - eval("class ".$name." extends ASN_BASE {}"); - } - - /** - * This function reset's the internal cursor used for value iteration. - */ - public function reset() - { - $this->cursor = 0; - } - - /** - * This function catches calls to get the value for the type, typeName, value, values, and data - * from the object. For type calls we just return the class name or the value of the constant that - * is named the same as the class. - */ - public function __get($name) - { - if ('type' == $name) { - // int flag of the data type - return constant(get_class($this)); - } elseif ('typeName' == $name) { - // name of the data type - return get_class($this); - } elseif ('value' == $name) { - // will always return one value and can be iterated over with: - // while ($v = $obj->value) { ... - // because $this->asnData["invalid key"] will return false - return is_array($this->asnData) ? $this->asnData[$this->cursor++] : $this->asnData; - } elseif ('values' == $name) { - // will always return an array - return is_array($this->asnData) ? $this->asnData : array($this->asnData); - } elseif ('data' == $name) { - // will always return the raw data - return $this->asnData; - } - } - - /** - * Parse an ASN.1 binary string. - * - * This function takes a binary ASN.1 string and parses it into it's respective - * pieces and returns it. It can optionally stop at any depth. - * - * @param string $string The binary ASN.1 String - * @param int $level The current parsing depth level - * @param int $maxLevel The max parsing depth level - * @return ASN_BASE The array representation of the ASN.1 data contained in $string - */ - public static function parseASNString($string=false, $level=1, $maxLevels=false){ - if (!class_exists('ASN_UNIVERSAL')) - self::generateSubclasses(); - if ($level>$maxLevels && $maxLevels) - return array(new ASN_BASE($string)); - $parsed = array(); - $endLength = strlen($string); - $bigLength = $length = $type = $dtype = $p = 0; - while ($p<$endLength){ - $type = ord($string[$p++]); - $dtype = ($type & 192) >> 6; - if ($type==0){ // if we are type 0, just continue - } else { - $length = ord($string[$p++]); - if (($length & ASN_LONG_LEN)==ASN_LONG_LEN){ - $tempLength = 0; - for ($x=0; $x<($length & (ASN_LONG_LEN-1)); $x++){ - $tempLength = ord($string[$p++]) + ($tempLength * 256); - } - $length = $tempLength; - } - $data = substr($string, $p, intval($length)); - $parsed[] = self::parseASNData($type, $data, $level, $maxLevels); - $p = $p + $length; - } - } - return $parsed; - } - - /** - * Parse an ASN.1 field value. - * - * This function takes a binary ASN.1 value and parses it according to it's specified type - * - * @param int $type The type of data being provided - * @param string $data The raw binary data string - * @param int $level The current parsing depth - * @param int $maxLevels The max parsing depth - * @return mixed The data that was parsed from the raw binary data string - */ - public static function parseASNData($type, $data, $level, $maxLevels){ - $type = $type%50; // strip out context - switch ($type){ - default: - return new ASN_BASE($data); - case ASN_BOOLEAN: - return new ASN_BOOLEAN((bool)$data); - case ASN_INTEGER: - return new ASN_INTEGER(strtr(base64_encode($data),'+/','-_')); - case ASN_BIT_STR: - return new ASN_BIT_STR(self::parseASNString($data, $level+1, $maxLevels)); - case ASN_OCTET_STR: - return new ASN_OCTET_STR($data); - case ASN_NULL: - return new ASN_NULL(null); - case ASN_REAL: - return new ASN_REAL($data); - case ASN_ENUMERATED: - return new ASN_ENUMERATED(self::parseASNString($data, $level+1, $maxLevels)); - case ASN_RELATIVE_OID: // I don't really know how this works and don't have an example :-) - // so, lets just return it ... - return new ASN_RELATIVE_OID($data); - case ASN_SEQUENCE: - return new ASN_SEQUENCE(self::parseASNString($data, $level+1, $maxLevels)); - case ASN_SET: - return new ASN_SET(self::parseASNString($data, $level+1, $maxLevels)); - case ASN_PRINT_STR: - return new ASN_PRINT_STR($data); - case ASN_IA5_STR: - return new ASN_IA5_STR($data); - case ASN_UTC_TIME: - return new ASN_UTC_TIME($data); - case ASN_GENERAL_TIME: - return new ASN_GENERAL_TIME($data); - case ASN_OBJECT_ID: - return new ASN_OBJECT_ID(self::parseOID($data)); - } - } - - /** - * Parse an ASN.1 OID value. - * - * This takes the raw binary string that represents an OID value and parses it into its - * dot notation form. example - 1.2.840.113549.1.1.5 - * look up OID's here: http://www.oid-info.com/ - * (the multi-byte OID section can be done in a more efficient way, I will fix it later) - * - * @param string $data The raw binary data string - * @return string The OID contained in $data - */ - public static function parseOID($string){ - $ret = floor(ord($string[0])/40)."."; - $ret .= (ord($string[0]) % 40); - $build = array(); - $cs = 0; - - for ($i=1; $i<strlen($string); $i++){ - $v = ord($string[$i]); - if ($v>127){ - $build[] = ord($string[$i])-ASN_BIT; - } elseif ($build){ - // do the build here for multibyte values - $build[] = ord($string[$i])-ASN_BIT; - // you know, it seems there should be a better way to do this... - $build = array_reverse($build); - $num = 0; - for ($x=0; $x<count($build); $x++){ - $mult = $x==0?1:pow(256, $x); - if ($x+1==count($build)){ - $value = ((($build[$x] & (ASN_BIT-1)) >> $x)) * $mult; - } else { - $value = ((($build[$x] & (ASN_BIT-1)) >> $x) ^ ($build[$x+1] << (7 - $x) & 255)) * $mult; - } - $num += $value; - } - $ret .= ".".$num; - $build = array(); // start over - } else { - $ret .= ".".$v; - $build = array(); - } - } - return $ret; - } - - public static function printASN($x, $indent=''){ - if (is_object($x)) { - echo $indent.$x->typeName."\n"; - if (ASN_NULL == $x->type) return; - if (is_array($x->data)) { - while ($d = $x->value) { - echo self::printASN($d, $indent.'. '); - } - $x->reset(); - } else { - echo self::printASN($x->data, $indent.'. '); - } - } elseif (is_array($x)) { - foreach ($x as $d) { - echo self::printASN($d, $indent); - } - } else { - if (preg_match('/[^[:print:]]/', $x)) // if we have non-printable characters that would - $x = base64_encode($x); // mess up the console, then print the base64 of them... - echo $indent.$x."\n"; - } - } - - -} - |