PageRenderTime 50ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/js/lib/Socket.IO-node/support/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSSocket.as

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