1 <?php
2 /*
3 * asnencode.php,v 1.0 2006/08/25 21:00:00
4 *
5 * Copyright 2006 Alejandro Escanero Blanco <aescanero@chaosdimension.org>
6 *
7 * See the enclosed file COPYING for license information (GPL). If you
8 * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
9 */
12 class stream{
14 var $stream;
15 var $len;
17 function stream(){
18 $this->stream=array();
19 $len=0;
20 }
22 function writeVal($val){
23 $val=($val & 0xff); //Only one byte
24 array_push($this->stream,$val);
25 $this->len++;
26 }
28 function writeArray($arr){
29 foreach ($arr as $val)
30 array_push($this->stream,$val);
32 $this->len+=count($arr);
33 }
35 function writeStream($stream){
36 $str=$stream->getStream();
37 // print_r($this->stream);
38 foreach ($str as $val)
39 array_push($this->stream,$val);
40 $this->len+=count($str);
41 }
43 function writeOctetString($os){
44 $len=strlen($os);
45 $arr=array($len);
46 for($i=0;$i<$len;$i++) $arr[$i]=ord(substr($os,$i,1));
47 $this->writeArray($arr);
48 }
50 function getStream(){
51 return($this->stream);
52 }
54 function getLen(){
55 return($this->len);
56 }
58 function printOut($debug=false,$msg=""){
59 if($debug) printf("%s len: %d\n",$msg,$this->len);
60 // print_r($this->stream);
61 $stringh="";
62 for ($i=0;$i<$this->len;$i++) $stringh.=sprintf(" %d %02x\n",$i,$this->stream[$i]);
63 printf("%s ASN: %s\n",$msg,$stringh);
64 }
66 function printString($debug=false,$msg=""){
67 $stringh="";
68 for ($i=0;$i<$this->len;$i++) $stringh.=chr($this->stream[$i]);
69 return($stringh);
70 }
71 };
73 define('UNIVERSAL',0x00);
75 define('INTEGER',0x02);
76 //define('INTEGER',0x80);
77 define('OCTET_STRING',0x04);
78 //define('OCTET_STRING',0x81);
79 define('NULL',0x05);
80 define('OBJECT_IDENTIFIER ',0x06);
81 define('SEQUENCE',0x10);
82 define('SEQUENCE_OF',0x10);
83 define('SET',0x11);
84 define('SET_OF',0x11);
88 class asnEncode{
90 var $stream;
92 function asnEncode(){
93 $this->stream=new stream();
94 }
96 function encodeOctetString($os){
97 $len=strlen($os);
98 $this->encodeTag(UNIVERSAL,OCTET_STRING,false,&$this->stream);
99 $this->encodeLen($len,&$this->stream);
100 $this->stream->writeOctetString($os);
101 }
103 function encodeTag($clazz,$value,$constructed,$stream){
104 if ($constructed)
105 $clazz |= 0x20;
106 if ($value < 0x1F){
107 $stream->writeVal($clazz | $value);
108 } else {
109 $stream->writeVal($clazz | 0x1F);
110 $clazz = $value;
111 while ($clazz > 63) {
112 $stream->writeVal(63);
113 $clazz -= 63;
114 }
115 $stream->writeVal($clazz);
116 }
117 return($stream);
118 }
120 function encodeInteger($val){
122 $dh=dechex($val);
123 $ldh=strlen($dh);
124 if($ldh%2 !=0){
125 $ldh="0".$ldh;
126 $ldh++;
127 }
128 $cero=0;
129 if($i==0)
130 if(hexdec(substr($dh,0,2))>127) $cero=1;
131 $this->encodeTag(UNIVERSAL,INTEGER,false,&$this->stream);
132 $this->encodeLen(($ldh/2)+$cero,&$this->stream);
133 for($i=0;$i<($ldh/2);$i++){
134 if($i==0 && $cero==1) $this->stream->writeVal(0);
135 $this->stream->writeVal(hexdec(substr($dh,$i*2,2)));
136 }
137 }
140 function encodeLen($val,$stream){
141 if ($val < 128) { // short definite form
142 $stream->writeVal($val);
143 return;
144 }
145 if ($val < 256) { // long definite form
146 //$this->stream->writeVal(-127);
147 $stream->writeVal(0x81);
148 $stream->writeVal($val);
149 return;
150 }
151 if ($val < 65536) {
152 //$this->stream->writeVal(-126);
153 $stream->writeVal(0x80);
154 $stream->writeVal($val >> 8);
155 $stream->writeVal($val);
156 return;
157 }
158 if ($val < 16777216) {
159 //$this->stream->writeVal(-125);
160 $stream->writeVal(0x79);
161 $stream->writeVal($val >> 16);
162 $stream->writeVal($val >> 8);
163 $stream->writeVal($val);
164 return;
165 }
166 //$this->stream->writeVal(-124);
167 $stream->writeVal(0x78);
168 $stream->writeVal($val >> 24);
169 $stream->writeVal($val >> 16);
170 $stream->writeVal($val >> 8);
171 $stream->writeVal($val);
172 return($stream);
173 }
175 function printOut(){
176 $this->stream->printOut();
177 }
179 function printString(){
180 return($this->stream->printString());
181 }
183 function getStream(){
184 return($this->stream);
185 }
187 function encodeSequence($ix,$stream){
188 $hix=0xa0+$ix;
189 $len=$stream->getLen();
190 $local=new stream();
191 $local->writeVal($hix);
192 $this->encodeLen($len,&$local);
193 $local->writeStream($stream);
194 $this->stream->writeStream($local);
195 return($local);
196 }
198 function encodeObject($tag,$stream){
199 $len=$stream->getLen();
200 //$this->encodeTag(UNIVERSAL,$tag,false,&$this->stream);
201 $this->stream->writeVal($tag);
202 $this->encodeLen($len,&$this->stream);
203 $this->stream->writeStream($stream);
204 }
206 };
208 ?>