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 };
74 class asnEncode{
76 var $stream;
78 function asnEncode(){
79 $this->stream=new stream();
80 }
82 function encodeOctetString($os){
83 $len=strlen($os);
84 $this->encodeTag(UNIVERSAL,OCTET_STRING,false,&$this->stream);
85 $this->encodeLen($len,&$this->stream);
86 $this->stream->writeOctetString($os);
87 }
89 function encodeTag($clazz,$value,$constructed,$stream){
90 if ($constructed)
91 $clazz |= 0x20;
92 if ($value < 0x1F){
93 $stream->writeVal($clazz | $value);
94 } else {
95 $stream->writeVal($clazz | 0x1F);
96 $clazz = $value;
97 while ($clazz > 63) {
98 $stream->writeVal(63);
99 $clazz -= 63;
100 }
101 $stream->writeVal($clazz);
102 }
103 return($stream);
104 }
106 function encodeInteger($val){
108 $dh=dechex($val);
109 $ldh=strlen($dh);
110 if($ldh%2 !=0){
111 $ldh="0".$ldh;
112 $ldh++;
113 }
114 $cero=0;
115 if($i==0)
116 if(hexdec(substr($dh,0,2))>127) $cero=1;
117 $this->encodeTag(UNIVERSAL,INTEGER,false,&$this->stream);
118 $this->encodeLen(($ldh/2)+$cero,&$this->stream);
119 for($i=0;$i<($ldh/2);$i++){
120 if($i==0 && $cero==1) $this->stream->writeVal(0);
121 $this->stream->writeVal(hexdec(substr($dh,$i*2,2)));
122 }
123 }
126 function encodeLen($val,$stream){
127 if ($val < 128) { // short definite form
128 $stream->writeVal($val);
129 return;
130 }
131 if ($val < 256) { // long definite form
132 //$this->stream->writeVal(-127);
133 $stream->writeVal(0x81);
134 $stream->writeVal($val);
135 return;
136 }
137 if ($val < 65536) {
138 //$this->stream->writeVal(-126);
139 $stream->writeVal(0x80);
140 $stream->writeVal($val >> 8);
141 $stream->writeVal($val);
142 return;
143 }
144 if ($val < 16777216) {
145 //$this->stream->writeVal(-125);
146 $stream->writeVal(0x79);
147 $stream->writeVal($val >> 16);
148 $stream->writeVal($val >> 8);
149 $stream->writeVal($val);
150 return;
151 }
152 //$this->stream->writeVal(-124);
153 $stream->writeVal(0x78);
154 $stream->writeVal($val >> 24);
155 $stream->writeVal($val >> 16);
156 $stream->writeVal($val >> 8);
157 $stream->writeVal($val);
158 return($stream);
159 }
161 function printOut(){
162 $this->stream->printOut();
163 }
165 function printString(){
166 return($this->stream->printString());
167 }
169 function getStream(){
170 return($this->stream);
171 }
173 function encodeSequence($ix,$stream){
174 $hix=0xa0+$ix;
175 $len=$stream->getLen();
176 $local=new stream();
177 $local->writeVal($hix);
178 $this->encodeLen($len,&$local);
179 $local->writeStream($stream);
180 $this->stream->writeStream($local);
181 return($local);
182 }
184 function encodeObject($tag,$stream){
185 $len=$stream->getLen();
186 //$this->encodeTag(UNIVERSAL,$tag,false,&$this->stream);
187 $this->stream->writeVal($tag);
188 $this->encodeLen($len,&$this->stream);
189 $this->stream->writeStream($stream);
190 }
192 };
194 ?>