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 / crypto / tls / TLSSocket.as
1 /**\r
2  * TLSSocket\r
3  * \r
4  * This is the "end-user" TLS class.\r
5  * It works just like a Socket, by encapsulating a Socket and\r
6  * wrapping the TLS protocol around the data that passes over it.\r
7  * This class can either create a socket connection, or reuse an\r
8  * existing connected socket. The later is useful for STARTTLS flows.\r
9  * \r
10  * Copyright (c) 2007 Henri Torgemane\r
11  * \r
12  * See LICENSE.txt for full license information.\r
13  */\r
14 package com.hurlant.crypto.tls {\r
15         import flash.events.Event;\r
16         import flash.events.EventDispatcher;\r
17         import flash.events.IOErrorEvent;\r
18         import flash.events.ProgressEvent;\r
19         import flash.events.SecurityErrorEvent;\r
20         import flash.net.ObjectEncoding;\r
21         import flash.net.Socket;\r
22         import flash.utils.ByteArray;\r
23         import flash.utils.Endian;\r
24         import flash.utils.IDataInput;\r
25         import flash.utils.IDataOutput;\r
26         import flash.utils.clearTimeout;\r
27         import flash.utils.setTimeout;
28         import com.hurlant.crypto.cert.X509Certificate;
29         \r
30         \r
31         [Event(name="close", type="flash.events.Event")]\r
32         [Event(name="connect", type="flash.events.Event")]\r
33         [Event(name="ioError", type="flash.events.IOErrorEvent")]\r
34         [Event(name="securityError", type="flash.events.SecurityErrorEvent")]\r
35         [Event(name="socketData", type="flash.events.ProgressEvent")]\r
36         [Event(name="acceptPeerCertificatePrompt", type="flash.events.Event")]\r
37         \r
38         /**\r
39          * It feels like a socket, but it wraps the stream\r
40          * over TLS 1.0\r
41          * \r
42          * That's all.\r
43          * \r
44          */\r
45         public class TLSSocket extends Socket implements IDataInput, IDataOutput {\r
46                 \r
47                 private var _endian:String;\r
48                 private var _objectEncoding:uint;\r
49                 \r
50                 private var _iStream:ByteArray;\r
51                 private var _oStream:ByteArray;\r
52                 private var _iStream_cursor:uint;\r
53                 \r
54                 private var _socket:Socket;\r
55                 private var _config:TLSConfig;\r
56                 private var _engine:TLSEngine;\r
57                 public static const ACCEPT_PEER_CERT_PROMPT:String = "acceptPeerCertificatePrompt"\r
58                 \r
59                 public function TLSSocket(host:String = null, port:int = 0, config:TLSConfig = null) {\r
60                         _config = config;\r
61                         if (host!=null && port!=0) {\r
62                                 connect(host, port);\r
63                         }\r
64                 }\r
65                 \r
66                 override public function get bytesAvailable():uint {\r
67                         return _iStream.bytesAvailable;\r
68                 }\r
69                 override public function get connected():Boolean {\r
70                         return _socket.connected;\r
71                 }\r
72                 override public function get endian():String {\r
73                         return _endian;\r
74                 }\r
75                 override public function set endian(value:String):void {\r
76                         _endian = value;\r
77                         _iStream.endian = value;\r
78                         _oStream.endian = value;\r
79                 }\r
80                 override public function get objectEncoding():uint {\r
81                         return _objectEncoding;\r
82                 }\r
83                 override public function set objectEncoding(value:uint):void {\r
84                         _objectEncoding = value;\r
85                         _iStream.objectEncoding = value;\r
86                         _oStream.objectEncoding = value;\r
87                 }\r
88                 \r
89                 \r
90                 private function onTLSData(event:TLSEvent):void {\r
91                         if (_iStream.position == _iStream.length) {\r
92                                 _iStream.position = 0;\r
93                                 _iStream.length = 0;\r
94                                 _iStream_cursor = 0;\r
95                         }\r
96                         var cursor:uint = _iStream.position;\r
97                         _iStream.position = _iStream_cursor;\r
98                         _iStream.writeBytes(event.data);\r
99                         _iStream_cursor = _iStream.position;\r
100                         _iStream.position = cursor;\r
101                         dispatchEvent(new ProgressEvent(ProgressEvent.SOCKET_DATA, false, false, event.data.length));\r
102                 }\r
103                 \r
104                 private function onTLSReady(event:TLSEvent):void {\r
105                         _ready = true;\r
106                         scheduleWrite();\r
107                 }\r
108                 \r
109                 private function onTLSClose(event:Event):void {\r
110                         dispatchEvent(event);\r
111                         // trace("Received TLS close");\r
112                         close();\r
113                 }\r
114                 \r
115                 private var _ready:Boolean;\r
116                 private var _writeScheduler:uint;\r
117                 private function scheduleWrite():void {\r
118                         if (_writeScheduler!=0) return;\r
119                         _writeScheduler = setTimeout(commitWrite, 0);\r
120                 }\r
121                 private function commitWrite():void {\r
122                         clearTimeout(_writeScheduler);\r
123                         _writeScheduler = 0;\r
124                         if (_ready) {\r
125                                 _engine.sendApplicationData(_oStream);\r
126                                 _oStream.length = 0;\r
127                         }\r
128                 }\r
129                 \r
130                 \r
131                 override public function close():void {\r
132                         _ready = false;\r
133                         _engine.close();\r
134                         if (_socket.connected) {\r
135                                 _socket.flush();\r
136                                 _socket.close();\r
137                         }\r
138                 }\r
139                 public function setTLSConfig( config:TLSConfig) : void {\r
140                         _config = config;\r
141                 }               \r
142 \r
143                 override public function connect(host:String, port:int):void {\r
144                         init(new Socket, _config, host);\r
145                         _socket.connect(host, port);\r
146                         _engine.start();\r
147                 }\r
148                 \r
149                 public function releaseSocket() : void {\r
150                         _socket.removeEventListener(Event.CONNECT, dispatchEvent);\r
151                         _socket.removeEventListener(IOErrorEvent.IO_ERROR, dispatchEvent);\r
152                         _socket.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, dispatchEvent);\r
153                         _socket.removeEventListener(Event.CLOSE, dispatchEvent);\r
154                         _socket.removeEventListener(ProgressEvent.SOCKET_DATA, _engine.dataAvailable);\r
155                         _socket = null; \r
156                 }\r
157                 \r
158                 public function reinitialize(host:String, config:TLSConfig) : void {\r
159                         // Reinitialize the connection using new values\r
160                         // but re-use the existing socket\r
161                         // Doubt this is useful in any valid context other than my specific case (VMWare)\r
162                         var ba:ByteArray = new ByteArray;\r
163                         \r
164                         if (_socket.bytesAvailable > 0) {\r
165                                 _socket.readBytes(ba, 0, _socket.bytesAvailable);       \r
166                         }\r
167                         // Do nothing with it.\r
168                         _iStream = new ByteArray;\r
169                         _oStream = new ByteArray;\r
170                         _iStream_cursor = 0;\r
171                         objectEncoding = ObjectEncoding.DEFAULT;\r
172                         endian = Endian.BIG_ENDIAN;\r
173                         /* \r
174                         _socket.addEventListener(Event.CONNECT, dispatchEvent);\r
175                         _socket.addEventListener(IOErrorEvent.IO_ERROR, dispatchEvent);\r
176                         _socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, dispatchEvent);\r
177                         _socket.addEventListener(Event.CLOSE, dispatchEvent);\r
178                         */\r
179                         \r
180                         if (config == null) {\r
181                                 config = new TLSConfig(TLSEngine.CLIENT);\r
182                         }\r
183                         \r
184                         _engine = new TLSEngine(config, _socket, _socket, host);\r
185                         _engine.addEventListener(TLSEvent.DATA, onTLSData);\r
186                         _engine.addEventListener(TLSEvent.READY, onTLSReady);\r
187                         _engine.addEventListener(Event.CLOSE, onTLSClose);\r
188                         _engine.addEventListener(ProgressEvent.SOCKET_DATA, function(e:*):void { _socket.flush(); });\r
189                         _socket.addEventListener(ProgressEvent.SOCKET_DATA, _engine.dataAvailable);\r
190                         _engine.addEventListener( TLSEvent.PROMPT_ACCEPT_CERT, onAcceptCert );\r
191 \r
192                         _ready = false;\r
193                         _engine.start();\r
194                 }\r
195                 \r
196                 public function startTLS(socket:Socket, host:String, config:TLSConfig = null):void {\r
197                         if (!socket.connected) {\r
198                                 throw new Error("Cannot STARTTLS on a socket that isn't connected.");\r
199                         }\r
200                         init(socket, config, host);\r
201                         _engine.start();\r
202                 }\r
203                 \r
204                 private function init(socket:Socket, config:TLSConfig, host:String):void {\r
205                         _iStream = new ByteArray;\r
206                         _oStream = new ByteArray;\r
207                         _iStream_cursor = 0;\r
208                         objectEncoding = ObjectEncoding.DEFAULT;\r
209                         endian = Endian.BIG_ENDIAN;\r
210                         _socket = socket;\r
211                         _socket.addEventListener(Event.CONNECT, dispatchEvent);\r
212                         _socket.addEventListener(IOErrorEvent.IO_ERROR, dispatchEvent);\r
213                         _socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, dispatchEvent);\r
214                         _socket.addEventListener(Event.CLOSE, dispatchEvent);\r
215                         \r
216                         if (config == null) {\r
217                                 config = new TLSConfig(TLSEngine.CLIENT);\r
218                         }\r
219                         _engine = new TLSEngine(config, _socket, _socket, host);\r
220                         _engine.addEventListener(TLSEvent.DATA, onTLSData);\r
221                         _engine.addEventListener( TLSEvent.PROMPT_ACCEPT_CERT, onAcceptCert );\r
222                         _engine.addEventListener(TLSEvent.READY, onTLSReady);\r
223                         _engine.addEventListener(Event.CLOSE, onTLSClose);\r
224                         _engine.addEventListener(ProgressEvent.SOCKET_DATA, function(e:*):void { if(connected) _socket.flush(); });\r
225                         _socket.addEventListener(ProgressEvent.SOCKET_DATA, _engine.dataAvailable);\r
226 \r
227                         _ready = false;\r
228                 }\r
229                 \r
230                 override public function flush():void {\r
231                         commitWrite();\r
232                         _socket.flush();\r
233                 }\r
234                 \r
235                 override public function readBoolean():Boolean {\r
236                         return _iStream.readBoolean();\r
237                 }\r
238                 \r
239                 override public function readByte():int {\r
240                         return _iStream.readByte();\r
241                 }\r
242                 \r
243                 override public function readBytes(bytes:ByteArray, offset:uint = 0, length:uint = 0):void {\r
244                         return _iStream.readBytes(bytes, offset, length);\r
245                 }\r
246                 \r
247                 override public function readDouble():Number {\r
248                         return _iStream.readDouble();\r
249                 }\r
250                 \r
251                 override public function readFloat():Number {\r
252                         return _iStream.readFloat();\r
253                 }\r
254                 \r
255                 override public function readInt():int {\r
256                         return _iStream.readInt();\r
257                 }\r
258                 \r
259                 override public function readMultiByte(length:uint, charSet:String):String {\r
260                         return _iStream.readMultiByte(length, charSet);\r
261                 }\r
262                 \r
263                 override public function readObject():* {\r
264                         return _iStream.readObject();\r
265                 }\r
266                 \r
267                 override public function readShort():int {\r
268                         return _iStream.readShort();\r
269                 }\r
270                 \r
271                 override public function readUnsignedByte():uint {\r
272                         return _iStream.readUnsignedByte();\r
273                 }\r
274                 \r
275                 override public function readUnsignedInt():uint {\r
276                         return _iStream.readUnsignedInt();\r
277                 }\r
278                 \r
279                 override public function readUnsignedShort():uint {\r
280                         return _iStream.readUnsignedShort();\r
281                 }\r
282                 \r
283                 override public function readUTF():String {\r
284                         return _iStream.readUTF();\r
285                 }\r
286                 \r
287                 override public function readUTFBytes(length:uint):String {\r
288                         return _iStream.readUTFBytes(length);\r
289                 }\r
290                 \r
291                 override public function writeBoolean(value:Boolean):void {\r
292                         _oStream.writeBoolean(value);\r
293                         scheduleWrite();\r
294                 }\r
295                 \r
296                 override public function writeByte(value:int):void {\r
297                         _oStream.writeByte(value);\r
298                         scheduleWrite();\r
299                 }\r
300                 \r
301                 override public function writeBytes(bytes:ByteArray, offset:uint = 0, length:uint = 0):void {\r
302                         _oStream.writeBytes(bytes, offset, length);\r
303                         scheduleWrite();\r
304                 }\r
305                 \r
306                 override public function writeDouble(value:Number):void {\r
307                         _oStream.writeDouble(value);\r
308                         scheduleWrite();\r
309                 }\r
310                 \r
311                 override public function writeFloat(value:Number):void {\r
312                         _oStream.writeFloat(value);\r
313                         scheduleWrite();\r
314                 }\r
315                 \r
316                 override public function writeInt(value:int):void {\r
317                         _oStream.writeInt(value);\r
318                         scheduleWrite();\r
319                 }\r
320                 \r
321                 override public function writeMultiByte(value:String, charSet:String):void {\r
322                         _oStream.writeMultiByte(value, charSet);\r
323                         scheduleWrite();\r
324                 }\r
325                 \r
326                 override public function writeObject(object:*):void {\r
327                         _oStream.writeObject(object);\r
328                         scheduleWrite();\r
329                 }\r
330                 \r
331                 override public function writeShort(value:int):void {\r
332                         _oStream.writeShort(value);\r
333                         scheduleWrite();\r
334                 }\r
335                 \r
336                 override public function writeUnsignedInt(value:uint):void {\r
337                         _oStream.writeUnsignedInt(value);\r
338                         scheduleWrite();\r
339                 }\r
340                 \r
341                 override public function writeUTF(value:String):void {\r
342                         _oStream.writeUTF(value);\r
343                         scheduleWrite();\r
344                 }\r
345                 \r
346                 override public function writeUTFBytes(value:String):void {\r
347                         _oStream.writeUTFBytes(value);\r
348                         scheduleWrite();\r
349                 }\r
350                 \r
351                 public function getPeerCertificate() : X509Certificate {\r
352                         return _engine.peerCertificate;\r
353                 }\r
354                 \r
355                 public function onAcceptCert( event:TLSEvent ) : void {\r
356                         dispatchEvent( new TLSSocketEvent( _engine.peerCertificate ) );\r
357                 }\r
358                 \r
359                 // These are just a passthroughs to the engine. Encapsulation, et al\r
360                 public function acceptPeerCertificate( event:Event ) : void {\r
361                         _engine.acceptPeerCertificate();\r
362                 }\r
363         \r
364                 public function rejectPeerCertificate( event:Event ) : void {\r
365                         _engine.rejectPeerCertificate();\r
366                 }\r
367                 \r
368         }\r
369 }\r
370         \r