phpPoA2
[ class tree: phpPoA2 ] [ index: phpPoA2 ] [ all elements ]

Source for file ASN1.php

Documentation is available at ASN1.php

  1. <?php
  2. /**
  3.  * @copyright Copyright 2005-2010 RedIRIS, http://www.rediris.es/
  4.  *
  5.  *  This file is part of phpPoA2.
  6.  *  
  7.  *  phpPoA2 is free software: you can redistribute it and/or modify
  8.  *  it under the terms of the GNU General Public License as published by
  9.  *  the Free Software Foundation, either version 3 of the License, or
  10.  *  (at your option) any later version.
  11.  *  
  12.  *  phpPoA2 is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *  GNU General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU General Public License
  18.  *  along with phpPoA2. If not, see <http://www.gnu.org/licenses/>.
  19.  *
  20.  * @license http://www.gnu.org/licenses/gpl.html GNU General Public License
  21.  * @version 2.0
  22.  * @author Jaime Perez <jaime.perez@rediris.es>
  23.  * @filesource
  24.  * 
  25.  *  Mostly based on code by A. Oliinyk.
  26.  */
  27.  
  28. /**
  29.  * Basic tags.
  30.  */
  31. define("TAG_BER"0x00);
  32. define("TAG_BOOLEAN"0x01);
  33. define("TAG_INTEGER"0x02);
  34. define("TAG_BITSTRING"0x03);
  35.  
  36.  
  37. /**
  38.  * Constructed tags.
  39.  */
  40. define("TAG_SEQUENCE"0x30);
  41.  
  42. /**
  43.  * This class implements ASN.1 encoding.
  44.  * Please, be aware that this class is INCOMPLETE, as it
  45.  * is intended for BER/DER encoding primarily.
  46.  *
  47.  * @package phpPoA2
  48.  * @subpackage crypto
  49.  */
  50. class ASN1 {
  51.  
  52.     public $tag;
  53.     public $value;
  54.  
  55.     /**
  56.      * Build a new ASN1 from its tag and value.
  57.      */
  58.     public function __construct($tag 0x00$value ''{
  59.         $this->tag = $tag;
  60.         $this->value = $value;
  61.     }
  62.  
  63.     /**
  64.      * Encode this object into ASN.1.
  65.      */
  66.     public function encode({
  67.         // set the tag
  68.         $encoded $this->tag;
  69.  
  70.         /*
  71.          * Write the length of the contents.
  72.          * Refer to ITU-T X.609 section 8.1.3 for details on how length must be encoded.
  73.          */
  74.         $len strlen($this->value);
  75.         if ($len 127// store in one byte
  76.             $encoded .= $this->writeByte($len);
  77.         else // store the length in separate bytes
  78.             $len $this->int2bin($len);
  79.  
  80.             // write long length
  81.             // first bit must be 1
  82.             $encoded .= $this->writeByte(strlen($len128);
  83.  
  84.             // write the bytes with real length
  85.             $encoded .= $len;
  86.         }
  87.  
  88.         // finally write the value
  89.         $encoded .= $this->value;
  90.  
  91.         return $encoded;
  92.     }
  93.  
  94.     /**
  95.      * Decode an object in ASN.1 format.
  96.      */
  97.     public function decode(&$buffer{
  98.         // get ASN.1 tag
  99.         $this->tag = $this->readByte($buffer);
  100.  
  101.         // get the length of de data
  102.         $byte $this->readByte($buffer);
  103.  
  104.         /*
  105.          * Read the real length.
  106.          * Refer to ITU-T X.609 section 8.1.3 for details on how length must be encoded.
  107.          */
  108.         // short length, stored in one byte
  109.         if ($byte 128{
  110.             $len $byte;
  111.         else if ($byte === 128{
  112.             // indefinite length, read until two zero bytes are found
  113.             $len 0;
  114.         else if ($byte 255{
  115.             // long length, from 1 up to 127 next bytes
  116.             $len $this->bin2int($this->readBytes($buffer$byte 128));
  117.         else {
  118.             // 255 found, reserved value
  119.             throw new Exception("Long length of 0x7f cannot be used. Reserved value.");
  120.         }
  121.  
  122.         // read the value
  123.         if ($len{
  124.             $this->value = $this->readBytes($buffer$len);
  125.         else {
  126.             // read until two zero bytes are found
  127.             $this->value = '';
  128.             while(true{
  129.                 $this->value .= $this->readByte($buffer);
  130.                 $len strlen($this->value);
  131.                 if ($len && $this->value{$len -2=== && $this->value{$len -1=== 0{
  132.                     // end-of-contents octets found, trim them
  133.                     $this->value = substr($this->value0$len 2);
  134.                     break;
  135.                 }
  136.             
  137.         }
  138.  
  139.     }
  140.  
  141.     /**
  142.      * Get the tag of this ASN.1.
  143.      */
  144.     public function getTag({
  145.         return $this->tag;
  146.     }
  147.  
  148.     /**
  149.      * Get the binary value of this ASN.1.
  150.      */
  151.     public function getValue({
  152.         if (!ord($this->value{0})) {
  153.             // if the first byte is null, remove it
  154.             return substr($this->value1);
  155.         }
  156.  
  157.         return $this->value;
  158.     }
  159.  
  160.     /**
  161.      * Set the binary value of this ASN.1.
  162.      */
  163.     public function setValue($value{
  164.         if (strlen($value1{
  165.             $byte ord($value{0});
  166.  
  167.             /*
  168.              * It is mandatory in ASN.1 to precede data by a null byte
  169.              * if the first bit of the data is set.
  170.              */
  171.             if ($byte 0x80{
  172.                 $value chr(0x00).$value;
  173.             }
  174.         }
  175.         $this->value $value;
  176.     }
  177.  
  178.     /**
  179.      * Get the integer value of this ASN.1.
  180.      */
  181.     public function getInteger({
  182.         return $this->bin2int($this->getValue());
  183.     }
  184.  
  185.     /**
  186.      * Set the value of this ASN.1 from an integer.
  187.      */
  188.     public function setInteger($int{
  189.         $this->setValue($this->int2bin($int));
  190.     }
  191.  
  192.     /**
  193.      * Get the sequence of values stored in this ASN.1.
  194.      */
  195.     public function getValues({
  196.         $result array();
  197.         $values $this->value;
  198.  
  199.         while (strlen($values)) {
  200.             $asn new ASN1();
  201.             $asn->decode($values);
  202.             $result[$asn;
  203.         }
  204.  
  205.         return $result;
  206.     }
  207.  
  208.     /**
  209.      * Set the value of this ASN.1 to be a sequence of values.
  210.      */
  211.     public function setValues($values{
  212.         $result '';
  213.  
  214.         foreach ($values as $value{
  215.             $result .= $value->encode();
  216.         }
  217.  
  218.         $this->value $result;
  219.     }
  220.  
  221.     /*********************
  222.      * PROTECTED METHODS *
  223.      *********************/
  224.  
  225.     /**
  226.      * Read n bytes from a buffer and mov the internal pointer.
  227.      */
  228.     protected function readBytes(&$buffer$length{
  229.         $result substr($buffer0$length);
  230.         $buffer substr($buffer$length);
  231.         return $result;
  232.     }
  233.  
  234.     /**
  235.      * Read first byte from the buffer and move the internal pointer.
  236.      */
  237.     protected function readByte(&$buffer{
  238.         return ord($this->readBytes($buffer1));
  239.     }
  240.  
  241.     /**
  242.      * Write bytes to a buffer.
  243.      */
  244.     protected function writeBytes(&$buffer$bytes{
  245.         for ($i 0$i strlen($bytes)$i++{
  246.             $this->writeByte($buffer$bytes{$i});
  247.         }
  248.     }
  249.  
  250.     /**
  251.      * Write a byte to a buffer.
  252.      */
  253.     protected function writeByte(&$buffer$byte{
  254.         $buffer .= chr($byte);
  255.     }
  256.  
  257.     /**
  258.      * Decode an integer from its binary representation.
  259.      */
  260.     protected function bin2int($bin{
  261.         $result 0;
  262.         $len strlen($bin);
  263.  
  264.         for ($i 0$i $len$i++{
  265.             $byte $this->readByte($bin);
  266.             $result += $byte << (($len $i 18);
  267.         }
  268.  
  269.         return $result;
  270.     }
  271.  
  272.     /**
  273.      * Encode an integer in binary representation.
  274.      */
  275.     protected function int2bin($int{
  276.         $result '';
  277.  
  278.         do {
  279.             $byte $int 256;
  280.             $result chr($byte).$result;
  281.  
  282.             $int ($int $byte256;
  283.         while ($int 0);
  284.  
  285.         return $result;
  286.     }
  287.  
  288. }
  289.  
  290. ?>

Documentation generated on Fri, 11 Feb 2011 10:57:54 +0100 by phpDocumentor 1.4.3