Bug:Fix file validation issue
[vnfsdk/refrepo.git] / vnfmarket / src / main / webapp / vnfmarket / node_modules / socket.io-client / lib / vendor / web-socket-js / flash-src / com / hurlant / util / der / DER.as
1 /**\r
2  * DER\r
3  * \r
4  * A basic class to parse DER structures.\r
5  * It is very incomplete, but sufficient to extract whatever data we need so far.\r
6  * Copyright (c) 2007 Henri Torgemane\r
7  * \r
8  * See LICENSE.txt for full license information.\r
9  */\r
10 package com.hurlant.util.der\r
11 {\r
12         import com.hurlant.math.BigInteger;\r
13         \r
14         import flash.utils.ByteArray;\r
15         import com.hurlant.util.der.Sequence;\r
16         import com.hurlant.util.Hex;\r
17         \r
18         // goal 1: to be able to parse an RSA Private Key PEM file.\r
19         // goal 2: to parse an X509v3 cert. kinda.\r
20         \r
21         /**\r
22          * DER for dummies:\r
23          * http://luca.ntop.org/Teaching/Appunti/asn1.html\r
24          * \r
25          * This class does the bare minimum to get by. if that.\r
26          */\r
27         public class DER\r
28         {\r
29                 public static var indent:String = "";\r
30                 \r
31                 public static function parse(der:ByteArray, structure:*=null):IAsn1Type {\r
32 /*                      if (der.position==0) {\r
33                                 trace("DER.parse: "+Hex.fromArray(der));\r
34                         }\r
35  */                     // type\r
36                         var type:int = der.readUnsignedByte();\r
37                         var constructed:Boolean = (type&0x20)!=0;\r
38                         type &=0x1F;\r
39                         // length\r
40                         var len:int = der.readUnsignedByte();\r
41                         if (len>=0x80) {\r
42                                 // long form of length\r
43                                 var count:int = len & 0x7f;\r
44                                 len = 0;\r
45                                 while (count>0) {\r
46                                         len = (len<<8) | der.readUnsignedByte();\r
47                                         count--;\r
48                                 }\r
49                         }\r
50                         // data\r
51                         var b:ByteArray\r
52                         switch (type) {\r
53                                 case 0x00: // WHAT IS THIS THINGY? (seen as 0xa0)\r
54                                         // (note to self: read a spec someday.)\r
55                                         // for now, treat as a sequence.\r
56                                 case 0x10: // SEQUENCE/SEQUENCE OF. whatever\r
57                                         // treat as an array\r
58                                         var p:int = der.position;\r
59                                         var o:Sequence = new Sequence(type, len);\r
60                                         var arrayStruct:Array = structure as Array;\r
61                                         if (arrayStruct!=null) {\r
62                                                 // copy the array, as we destroy it later.\r
63                                                 arrayStruct = arrayStruct.concat();\r
64                                         }\r
65                                         while (der.position < p+len) {\r
66                                                 var tmpStruct:Object = null\r
67                                                 if (arrayStruct!=null) {\r
68                                                         tmpStruct = arrayStruct.shift();\r
69                                                 }\r
70                                                 if (tmpStruct!=null) {\r
71                                                         while (tmpStruct && tmpStruct.optional) {\r
72                                                                 // make sure we have something that looks reasonable. XXX I'm winging it here..\r
73                                                                 var wantConstructed:Boolean = (tmpStruct.value is Array);\r
74                                                                 var isConstructed:Boolean = isConstructedType(der);\r
75                                                                 if (wantConstructed!=isConstructed) {\r
76                                                                         // not found. put default stuff, or null\r
77                                                                         o.push(tmpStruct.defaultValue);\r
78                                                                         o[tmpStruct.name] = tmpStruct.defaultValue;\r
79                                                                         // try the next thing\r
80                                                                         tmpStruct = arrayStruct.shift();\r
81                                                                 } else {\r
82                                                                         break;\r
83                                                                 }\r
84                                                         }\r
85                                                 }\r
86                                                 if (tmpStruct!=null) {\r
87                                                         var name:String = tmpStruct.name;\r
88                                                         var value:* = tmpStruct.value;\r
89                                                         if (tmpStruct.extract) {\r
90                                                                 // we need to keep a binary copy of this element\r
91                                                                 var size:int = getLengthOfNextElement(der);\r
92                                                                 var ba:ByteArray = new ByteArray;\r
93                                                                 ba.writeBytes(der, der.position, size);\r
94                                                                 o[name+"_bin"] = ba;\r
95                                                         }\r
96                                                         var obj:IAsn1Type = DER.parse(der, value);\r
97                                                         o.push(obj);\r
98                                                         o[name] = obj;\r
99                                                 } else {\r
100                                                         o.push(DER.parse(der));\r
101                                                 }\r
102                                         }\r
103                                         return o;\r
104                                 case 0x11: // SET/SET OF\r
105                                         p = der.position;\r
106                                         var s:Set = new Set(type, len);\r
107                                         while (der.position < p+len) {\r
108                                                 s.push(DER.parse(der));\r
109                                         }\r
110                                         return s;\r
111                                 case 0x02: // INTEGER\r
112                                         // put in a BigInteger\r
113                                         b = new ByteArray;\r
114                                         der.readBytes(b,0,len);\r
115                                         b.position=0;\r
116                                         return new Integer(type, len, b);\r
117                                 case 0x06: // OBJECT IDENTIFIER:\r
118                                         b = new ByteArray;\r
119                                         der.readBytes(b,0,len);\r
120                                         b.position=0;\r
121                                         return new ObjectIdentifier(type, len, b);\r
122                                 default:\r
123                                         trace("I DONT KNOW HOW TO HANDLE DER stuff of TYPE "+type);\r
124                                         // fall through\r
125                                 case 0x03: // BIT STRING\r
126                                         if (der[der.position]==0) {\r
127                                                 //trace("Horrible Bit String pre-padding removal hack."); // I wish I had the patience to find a spec for this.\r
128                                                 der.position++;\r
129                                                 len--;\r
130                                         }\r
131                                 case 0x04: // OCTET STRING\r
132                                         // stuff in a ByteArray for now.\r
133                                         var bs:ByteString = new ByteString(type, len);\r
134                                         der.readBytes(bs,0,len);\r
135                                         return bs;\r
136                                 case 0x05: // NULL\r
137                                         // if len!=0, something's horribly wrong.\r
138                                         // should I check?\r
139                                         return null;\r
140                                 case 0x13: // PrintableString\r
141                                         var ps:PrintableString = new PrintableString(type, len);\r
142                                         ps.setString(der.readMultiByte(len, "US-ASCII"));\r
143                                         return ps;\r
144                                 case 0x22: // XXX look up what this is. openssl uses this to store my email.\r
145                                 case 0x14: // T61String - an horrible format we don't even pretend to support correctly\r
146                                         ps = new PrintableString(type, len);\r
147                                         ps.setString(der.readMultiByte(len, "latin1"));\r
148                                         return ps;\r
149                                 case 0x17: // UTCTime\r
150                                         var ut:UTCTime = new UTCTime(type, len);\r
151                                         ut.setUTCTime(der.readMultiByte(len, "US-ASCII"));\r
152                                         return ut;\r
153                         }\r
154                 }\r
155                 \r
156                 private static function getLengthOfNextElement(b:ByteArray):int {\r
157                         var p:uint = b.position;\r
158                         // length\r
159                         b.position++;\r
160                         var len:int = b.readUnsignedByte();\r
161                         if (len>=0x80) {\r
162                                 // long form of length\r
163                                 var count:int = len & 0x7f;\r
164                                 len = 0;\r
165                                 while (count>0) {\r
166                                         len = (len<<8) | b.readUnsignedByte();\r
167                                         count--;\r
168                                 }\r
169                         }\r
170                         len += b.position-p; // length of length\r
171                         b.position = p;\r
172                         return len;\r
173                 }\r
174                 private static function isConstructedType(b:ByteArray):Boolean {\r
175                         var type:int = b[b.position];\r
176                         return (type&0x20)!=0;\r
177                 }\r
178                 \r
179                 public static function wrapDER(type:int, data:ByteArray):ByteArray {\r
180                         var d:ByteArray = new ByteArray;\r
181                         d.writeByte(type);\r
182                         var len:int = data.length;\r
183                         if (len<128) {\r
184                                 d.writeByte(len);\r
185                         } else if (len<256) {\r
186                                 d.writeByte(1 | 0x80);\r
187                                 d.writeByte(len);\r
188                         } else if (len<65536) {\r
189                                 d.writeByte(2 | 0x80);\r
190                                 d.writeByte(len>>8);\r
191                                 d.writeByte(len);\r
192                         } else if (len<65536*256) {\r
193                                 d.writeByte(3 | 0x80);\r
194                                 d.writeByte(len>>16);\r
195                                 d.writeByte(len>>8);\r
196                                 d.writeByte(len);\r
197                         } else {\r
198                                 d.writeByte(4 | 0x80);\r
199                                 d.writeByte(len>>24);\r
200                                 d.writeByte(len>>16);\r
201                                 d.writeByte(len>>8);\r
202                                 d.writeByte(len);\r
203                         }\r
204                         d.writeBytes(data);\r
205                         d.position=0;\r
206                         return d;\r
207                         \r
208                 }\r
209         }\r
210 }