rocket-js 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. data/Rakefile +5 -52
  2. data/spec/ruby/spec_helper.rb +2 -1
  3. metadata +7 -129
  4. data/src/vendor/web-socket-js/FABridge.js +0 -604
  5. data/src/vendor/web-socket-js/README.txt +0 -109
  6. data/src/vendor/web-socket-js/WebSocketMain.swf +0 -0
  7. data/src/vendor/web-socket-js/WebSocketMainInsecure.zip +0 -0
  8. data/src/vendor/web-socket-js/flash-src/WebSocket.as +0 -473
  9. data/src/vendor/web-socket-js/flash-src/WebSocketMain.as +0 -88
  10. data/src/vendor/web-socket-js/flash-src/WebSocketMainInsecure.as +0 -19
  11. data/src/vendor/web-socket-js/flash-src/WebSocketStateEvent.as +0 -32
  12. data/src/vendor/web-socket-js/flash-src/bridge/FABridge.as +0 -943
  13. data/src/vendor/web-socket-js/flash-src/build.sh +0 -10
  14. data/src/vendor/web-socket-js/flash-src/com/adobe/net/proxies/RFC2817Socket.as +0 -204
  15. data/src/vendor/web-socket-js/flash-src/com/gsolo/encryption/MD5.as +0 -375
  16. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/Crypto.as +0 -287
  17. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/cert/MozillaRootCertificates.as +0 -3235
  18. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/cert/X509Certificate.as +0 -218
  19. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/cert/X509CertificateCollection.as +0 -57
  20. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/HMAC.as +0 -82
  21. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/IHMAC.as +0 -27
  22. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/IHash.as +0 -21
  23. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/MAC.as +0 -137
  24. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/MD2.as +0 -124
  25. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/MD5.as +0 -204
  26. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/SHA1.as +0 -106
  27. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/SHA224.as +0 -28
  28. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/SHA256.as +0 -115
  29. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/SHABase.as +0 -71
  30. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/prng/ARC4.as +0 -90
  31. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/prng/IPRNG.as +0 -20
  32. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/prng/Random.as +0 -119
  33. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/prng/TLSPRF.as +0 -142
  34. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/rsa/RSAKey.as +0 -339
  35. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/AESKey.as +0 -2797
  36. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/BlowFishKey.as +0 -375
  37. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/CBCMode.as +0 -55
  38. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/CFB8Mode.as +0 -61
  39. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/CFBMode.as +0 -64
  40. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/CTRMode.as +0 -58
  41. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/DESKey.as +0 -365
  42. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/ECBMode.as +0 -86
  43. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/ICipher.as +0 -21
  44. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/IMode.as +0 -15
  45. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/IPad.as +0 -32
  46. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/IStreamCipher.as +0 -21
  47. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/ISymmetricKey.as +0 -35
  48. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/IVMode.as +0 -110
  49. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/NullPad.as +0 -34
  50. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/OFBMode.as +0 -52
  51. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/PKCS5.as +0 -44
  52. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/SSLPad.as +0 -44
  53. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/SimpleIVMode.as +0 -60
  54. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/TLSPad.as +0 -42
  55. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/TripleDESKey.as +0 -88
  56. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/XTeaKey.as +0 -94
  57. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/aeskey.pl +0 -29
  58. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/dump.txt +0 -2304
  59. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/AESKeyTest.as +0 -1220
  60. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/ARC4Test.as +0 -58
  61. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/BigIntegerTest.as +0 -39
  62. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/BlowFishKeyTest.as +0 -148
  63. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/CBCModeTest.as +0 -160
  64. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/CFB8ModeTest.as +0 -71
  65. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/CFBModeTest.as +0 -98
  66. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/CTRModeTest.as +0 -109
  67. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/DESKeyTest.as +0 -112
  68. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/ECBModeTest.as +0 -151
  69. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/HMACTest.as +0 -184
  70. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/ITestHarness.as +0 -20
  71. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/MD2Test.as +0 -56
  72. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/MD5Test.as +0 -58
  73. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/OFBModeTest.as +0 -101
  74. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/RSAKeyTest.as +0 -92
  75. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/SHA1Test.as +0 -198
  76. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/SHA224Test.as +0 -58
  77. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/SHA256Test.as +0 -60
  78. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/TLSPRFTest.as +0 -51
  79. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/TestCase.as +0 -42
  80. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/TripleDESKeyTest.as +0 -59
  81. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/XTeaKeyTest.as +0 -66
  82. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/BulkCiphers.as +0 -102
  83. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/CipherSuites.as +0 -117
  84. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/IConnectionState.as +0 -14
  85. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/ISecurityParameters.as +0 -29
  86. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/KeyExchanges.as +0 -24
  87. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/MACs.as +0 -38
  88. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/SSLConnectionState.as +0 -171
  89. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/SSLEvent.as +0 -26
  90. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/SSLSecurityParameters.as +0 -340
  91. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSConfig.as +0 -70
  92. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSConnectionState.as +0 -151
  93. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSEngine.as +0 -895
  94. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSError.as +0 -39
  95. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSEvent.as +0 -27
  96. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSSecurityParameters.as +0 -197
  97. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSSocket.as +0 -370
  98. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSSocketEvent.as +0 -26
  99. data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSTest.as +0 -180
  100. data/src/vendor/web-socket-js/flash-src/com/hurlant/math/BarrettReduction.as +0 -90
  101. data/src/vendor/web-socket-js/flash-src/com/hurlant/math/BigInteger.as +0 -1543
  102. data/src/vendor/web-socket-js/flash-src/com/hurlant/math/ClassicReduction.as +0 -35
  103. data/src/vendor/web-socket-js/flash-src/com/hurlant/math/IReduction.as +0 -11
  104. data/src/vendor/web-socket-js/flash-src/com/hurlant/math/MontgomeryReduction.as +0 -85
  105. data/src/vendor/web-socket-js/flash-src/com/hurlant/math/NullReduction.as +0 -34
  106. data/src/vendor/web-socket-js/flash-src/com/hurlant/math/bi_internal.as +0 -11
  107. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/ArrayUtil.as +0 -25
  108. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/Base64.as +0 -189
  109. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/Hex.as +0 -66
  110. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/Memory.as +0 -28
  111. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/ByteString.as +0 -43
  112. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/DER.as +0 -210
  113. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/IAsn1Type.as +0 -21
  114. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/Integer.as +0 -44
  115. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/OID.as +0 -35
  116. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/ObjectIdentifier.as +0 -112
  117. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/PEM.as +0 -118
  118. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/PrintableString.as +0 -49
  119. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/Sequence.as +0 -90
  120. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/Set.as +0 -27
  121. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/Type.as +0 -94
  122. data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/UTCTime.as +0 -60
  123. data/src/vendor/web-socket-js/sample.html +0 -76
  124. data/src/vendor/web-socket-js/swfobject.js +0 -4
  125. data/src/vendor/web-socket-js/web_socket.js +0 -388
@@ -1,895 +0,0 @@
1
- /**
2
- * TLSEngine
3
- *
4
- * A TLS protocol implementation.
5
- * See comment below for some details.
6
- * Copyright (c) 2007 Henri Torgemane
7
- *
8
- * Patched(heavily) by Bobby Parker (shortwave@gmail.com)
9
- *
10
- * See LICENSE.txt for full license information.
11
- */
12
- package com.hurlant.crypto.tls {
13
- import com.hurlant.crypto.cert.X509Certificate;
14
- import com.hurlant.crypto.cert.X509CertificateCollection;
15
- import com.hurlant.crypto.prng.Random;
16
- import com.hurlant.util.ArrayUtil;
17
- import com.hurlant.util.Hex;
18
-
19
- import flash.events.Event;
20
- import flash.events.EventDispatcher;
21
- import flash.events.ProgressEvent;
22
- import flash.utils.ByteArray;
23
- import flash.utils.IDataInput;
24
- import flash.utils.IDataOutput;
25
- import flash.utils.clearTimeout;
26
- import flash.utils.setTimeout;
27
- import com.hurlant.crypto.prng.ARC4;
28
-
29
-
30
- [Event(name="close", type="flash.events.Event")]
31
- [Event(name="socketData", type="flash.events.ProgressEvent")]
32
- [Event(name="ready", type="com.hurlant.crypto.tls.TLSEvent")]
33
- [Event(name="data", type="com.hurlant.crypto.tls.TLSEvent")]
34
-
35
- /**
36
- * The heart of the TLS protocol.
37
- * This class can work in server or client mode.
38
- *
39
- * This doesn't fully implement the TLS protocol.
40
- *
41
- * Things missing that I'd like to add:
42
- * - support for client-side certificates
43
- * - general code clean-up to make sure we don't have gaping securite holes
44
- *
45
- * Things that aren't there that I won't add:
46
- * - support for "export" cypher suites (deprecated in later TLS versions)
47
- * - support for "anon" cypher suites (deprecated in later TLS versions)
48
- *
49
- * Things that I'm unsure about adding later:
50
- * - compression. Compressing encrypted streams is barely worth the CPU cycles.
51
- * - diffie-hellman based key exchange mechanisms. Nifty, but would we miss it?
52
- *
53
- * @author henri
54
- *
55
- */
56
- public class TLSEngine extends EventDispatcher {
57
-
58
- public static const SERVER:uint = 0;
59
- public static const CLIENT:uint = 1;
60
- public var protocol_version:uint;
61
-
62
-
63
-
64
- private static const PROTOCOL_HANDSHAKE:uint = 22;
65
- private static const PROTOCOL_ALERT:uint = 21;
66
- private static const PROTOCOL_CHANGE_CIPHER_SPEC:uint = 20;
67
- private static const PROTOCOL_APPLICATION_DATA:uint = 23;
68
-
69
-
70
- private static const STATE_NEW:uint = 0; // brand new. nothing happened yet
71
- private static const STATE_NEGOTIATING:uint = 1; // we're figuring out what to use
72
- private static const STATE_READY:uint = 2; // we're ready for AppData stuff to go over us.
73
- private static const STATE_CLOSED:uint = 3; // we're done done.
74
-
75
- private var _entity:uint; // SERVER | CLIENT
76
- private var _config:TLSConfig;
77
-
78
- private var _state:uint;
79
-
80
- private var _securityParameters:ISecurityParameters;
81
-
82
- private var _currentReadState:IConnectionState;
83
- private var _currentWriteState:IConnectionState;
84
- private var _pendingReadState:IConnectionState;
85
- private var _pendingWriteState:IConnectionState;
86
-
87
- private var _handshakePayloads:ByteArray;
88
- private var _handshakeRecords:ByteArray; // For client-side certificate verify
89
-
90
- private var _iStream:IDataInput;
91
- private var _oStream:IDataOutput;
92
-
93
- // temporary store for X509 certs received by this engine.
94
- private var _store:X509CertificateCollection;
95
- // the main certificate received from the other side.
96
- private var _otherCertificate:X509Certificate;
97
-
98
- public function get peerCertificate() : X509Certificate {
99
- return _otherCertificate;
100
- }
101
- // If this isn't null, we expect this identity to be found in the Cert's Subject CN.
102
- private var _otherIdentity:String;
103
-
104
- // The client-side cert
105
- private var _myCertficate:X509Certificate;
106
- // My Identity
107
- private var _myIdentity:String;
108
-
109
- /**
110
- *
111
- * @param config A TLSConfig instance describing how we're supposed to work
112
- * @param iStream An input stream to read TLS data from
113
- * @param oStream An output stream to write TLS data to
114
- * @param otherIdentity An optional identifier. If set, this will be checked against the Subject CN of the other side's certificate.
115
- *
116
- */
117
- function TLSEngine(config:TLSConfig, iStream:IDataInput, oStream:IDataOutput, otherIdentity:String = null) {
118
- _entity = config.entity;
119
- _config = config;
120
- _iStream = iStream;
121
- _oStream = oStream;
122
- _otherIdentity = otherIdentity;
123
-
124
- _state = STATE_NEW;
125
-
126
- // Pick the right set of callbacks
127
- _entityHandshakeHandlers = _entity == CLIENT ? handshakeHandlersClient : handshakeHandlersServer;
128
-
129
- // setting up new security parameters needs to be controlled by...something.
130
- if (_config.version == SSLSecurityParameters.PROTOCOL_VERSION) {
131
- _securityParameters = new SSLSecurityParameters(_entity);
132
- } else {
133
- _securityParameters = new TLSSecurityParameters(_entity, _config.certificate, _config.privateKey);
134
- }
135
- protocol_version = _config.version;
136
-
137
- // So this...why is it here, other than to preclude a possible null pointer situation?
138
- var states:Object = _securityParameters.getConnectionStates();
139
-
140
- _currentReadState = states.read;
141
- _currentWriteState = states.write;
142
-
143
- _handshakePayloads = new ByteArray;
144
-
145
- _store = new X509CertificateCollection;
146
- }
147
-
148
- /**
149
- * This starts the TLS negotiation for a TLS Client.
150
- *
151
- * This is a no-op for a TLS Server.
152
- *
153
- */
154
- public function start():void {
155
- if (_entity == CLIENT) {
156
- try {
157
- startHandshake();
158
- } catch (e:TLSError) {
159
- handleTLSError(e);
160
- }
161
- }
162
- }
163
-
164
-
165
- public function dataAvailable(e:* = null):void {
166
- if (_state == STATE_CLOSED) return; // ignore
167
- try {
168
- parseRecord(_iStream);
169
- } catch (e:TLSError) {
170
- handleTLSError(e);
171
- }
172
- }
173
-
174
- public function close(e:TLSError = null):void {
175
- if (_state == STATE_CLOSED) return; // ignore
176
- // ok. send an Alert to let the peer know
177
- var rec:ByteArray = new ByteArray;
178
- if (e==null && _state != STATE_READY) {
179
- // use canceled while handshaking. be nice about it
180
- rec[0] = 1;
181
- rec[1] = TLSError.user_canceled;
182
- sendRecord(PROTOCOL_ALERT, rec);
183
- }
184
- rec[0] = 2;
185
- if (e == null) {
186
- rec[1] = TLSError.close_notify;
187
- } else {
188
- rec[1] = e.errorID;
189
- trace("TLSEngine shutdown triggered by "+e);
190
- }
191
- sendRecord(PROTOCOL_ALERT, rec);
192
-
193
- _state = STATE_CLOSED;
194
- dispatchEvent(new Event(Event.CLOSE));
195
- }
196
-
197
- private var _packetQueue:Array = [];
198
- private function parseRecord(stream:IDataInput):void {
199
- var p:ByteArray;
200
- while(_state!=STATE_CLOSED && stream.bytesAvailable>4) {
201
-
202
- if (_packetQueue.length>0) {
203
- var packet:Object = _packetQueue.shift();
204
- p = packet.data;
205
- if (stream.bytesAvailable+p.length>=packet.length) {
206
- // we have a whole packet. put together.
207
- stream.readBytes(p, p.length, packet.length-p.length);
208
- parseOneRecord(packet.type, packet.length, p);
209
- // do another loop to parse any leftover record
210
- continue;
211
- } else {
212
- // not enough. grab the data and park it.
213
- stream.readBytes(p, p.length, stream.bytesAvailable);
214
- _packetQueue.push(packet);
215
- continue;
216
- }
217
- }
218
-
219
-
220
- var type:uint = stream.readByte();
221
- var ver:uint = stream.readShort();
222
- var length:uint = stream.readShort();
223
- if (length>16384+2048) { // support compression and encryption overhead.
224
- throw new TLSError("Excessive TLS Record length: "+length, TLSError.record_overflow);
225
- }
226
- // Can pretty much assume that if I'm here, I've got a default config, so let's use it.
227
- if (ver != _securityParameters.version ) {
228
- throw new TLSError("Unsupported TLS version: "+ver.toString(16), TLSError.protocol_version);
229
- }
230
-
231
- p = new ByteArray;
232
- var actualLength:uint = Math.min(stream.bytesAvailable, length);
233
- stream.readBytes(p, 0, actualLength);
234
- if (actualLength == length) {
235
- parseOneRecord(type, length, p);
236
- } else {
237
- _packetQueue.push({type:type, length:length, data:p});
238
- }
239
- }
240
- }
241
-
242
-
243
- // Protocol handler map, provides a mapping of protocol types to individual packet handlers
244
- private var protocolHandlers:Object = { 23 : parseApplicationData, // PROTOCOL_APPLICATION_DATA
245
- 22 : parseHandshake, // PROTOCOL_HANDSHAKE
246
- 21 : parseAlert, // PROTOCOL_ALERT
247
- 20 : parseChangeCipherSpec }; // PROTOCOL_CHANGE_CIPHER_SPEC
248
-
249
- /**
250
- * Modified to support the notion of a handler map(see above ), since it makes for better clarity (IMHO of course).
251
- */
252
- private function parseOneRecord(type:uint, length:uint, p:ByteArray):void {
253
- p = _currentReadState.decrypt(type, length, p);
254
- if (p.length>16384) {
255
- throw new TLSError("Excessive Decrypted TLS Record length: "+p.length, TLSError.record_overflow);
256
- }
257
- if (protocolHandlers.hasOwnProperty( type )) {
258
- while( p != null)
259
- p = protocolHandlers[ type ]( p );
260
- } else {
261
- throw new TLSError("Unsupported TLS Record Content Type: "+type.toString( 16 ), TLSError.unexpected_message);
262
- }
263
- }
264
-
265
- ///////// handshake handling
266
- // session identifier
267
- // peer certificate
268
- // compression method
269
- // cipher spec
270
- // master secret
271
- // is resumable
272
- private static const HANDSHAKE_HELLO_REQUEST:uint = 0;
273
- private static const HANDSHAKE_CLIENT_HELLO:uint = 1;
274
- private static const HANDSHAKE_SERVER_HELLO:uint = 2;
275
- private static const HANDSHAKE_CERTIFICATE:uint = 11;
276
- private static const HANDSHAKE_SERVER_KEY_EXCHANGE:uint = 12;
277
- private static const HANDSHAKE_CERTIFICATE_REQUEST:uint = 13;
278
- private static const HANDSHAKE_HELLO_DONE:uint = 14;
279
- private static const HANDSHAKE_CERTIFICATE_VERIFY:uint = 15;
280
- private static const HANDSHAKE_CLIENT_KEY_EXCHANGE:uint = 16;
281
- private static const HANDSHAKE_FINISHED:uint = 20;
282
-
283
- // Server handshake handler map
284
- private var handshakeHandlersServer:Object = { 0 : notifyStateError, // HANDSHAKE_HELLO_REQUEST
285
- 1 : parseHandshakeClientHello, // HANDSHAKE_CLIENT_HELLO
286
- 2 : notifyStateError, // HANDSHAKE_SERVER_HELLO
287
- 11 : loadCertificates, // HANDSHAKE_CERTIFICATE
288
- 12 : notifyStateError, // HANDSHAKE_SERVER_KEY_EXCHANGE
289
- 13 : notifyStateError, // HANDSHAKE_CERTIFICATE_REQUEST
290
- 14 : notifyStateError, // HANDSHAKE_HELLO_DONE
291
- 15 : notifyStateError, // HANDSHAKE_CERTIFICATE_VERIFY
292
- 16 : parseHandshakeClientKeyExchange, // HANDSHAKE_CLIENT_KEY_EXCHANGE
293
- 20 : verifyHandshake // HANDSHAKE_FINISHED
294
- };
295
-
296
- // Client handshake handler map
297
- private var handshakeHandlersClient:Object = { 0 : parseHandshakeHello, // HANDSHAKE_HELLO_REQUEST
298
- 1 : notifyStateError, // HANDSHAKE_CLIENT_HELLO
299
- 2 : parseHandshakeServerHello, // HANDSHAKE_SERVER_HELLO
300
- 11 : loadCertificates, // HANDSHAKE_CERTIFICATE
301
- 12 : parseServerKeyExchange, // HANDSHAKE_SERVER_KEY_EXCHANGE
302
- 13 : setStateRespondWithCertificate, // HANDSHAKE_CERTIFICATE
303
- 14 : sendClientAck, // HANDSHAKE_HELLO_DONE
304
- 15 : notifyStateError, // HANDSHAKE_CERTIFICATE_VERIFY
305
- 16 : notifyStateError, // HANDSHAKE_CLIENT_KEY_EXCHANGE
306
- 20 : verifyHandshake // HANDSHAKE_FINISHED
307
- };
308
- private var _entityHandshakeHandlers:Object;
309
- private var _handshakeCanContinue:Boolean = true; // For handling cases where I might need to pause processing during a handshake (cert issues, etc.).
310
- private var _handshakeQueue:Array = [];
311
- /**
312
- * The handshake is always started by the client.
313
- */
314
- private function startHandshake():void {
315
- _state = STATE_NEGOTIATING;
316
- // reset some other handshake state. XXX
317
- sendClientHello();
318
- }
319
-
320
- /**
321
- * Handle the incoming handshake packet.
322
- *
323
- */
324
- private function parseHandshake(p:ByteArray):ByteArray {
325
-
326
- if (p.length<4) {
327
- trace("Handshake packet is way too short. bailing.");
328
- return null;
329
- }
330
-
331
- p.position = 0;
332
-
333
- var rec:ByteArray = p;
334
- var type:uint = rec.readUnsignedByte();
335
- var tmp:uint = rec.readUnsignedByte();
336
- var length:uint = (tmp<<16) | rec.readUnsignedShort();
337
- if (length+4>p.length) {
338
- // partial read.
339
- trace("Handshake packet is incomplete. bailing.");
340
- return null;
341
- }
342
-
343
- // we need to copy the record, to have a valid FINISHED exchange.
344
- if (type!=HANDSHAKE_FINISHED) {
345
- _handshakePayloads.writeBytes(p, 0, length+4);
346
- }
347
-
348
- // Surf the handler map and find the right handler for this handshake packet type.
349
- // I modified the individual handlers so they encapsulate all possible knowledge
350
- // about the incoming packet type, so no previous handling or massaging of the data
351
- // is required, as was the case using the switch statement. BP
352
- if (_entityHandshakeHandlers.hasOwnProperty( type )) {
353
- if (_entityHandshakeHandlers[ type ] is Function)
354
- _entityHandshakeHandlers[ type ]( rec );
355
- } else {
356
- throw new TLSError( "Unimplemented or unknown handshake type!", TLSError.internal_error );
357
- }
358
-
359
- // Get set up for the next packet.
360
- if (length+4<p.length) {
361
- var n:ByteArray = new ByteArray;
362
- n.writeBytes(p,length+4, p.length-(length+4));
363
- return n;
364
- } else {
365
- return null;
366
- }
367
- }
368
-
369
- /**
370
- * Throw an error when the detected handshake state isn't a valid state for the given entity type (client vs. server, etc. ).
371
- * This really should abort the handshake, since there's no case in which a server should EVER be confused about the type of entity it is. BP
372
- */
373
- private function notifyStateError( rec:ByteArray ) : void {
374
- throw new TLSError( "Invalid handshake state for a TLS Entity type of " + _entity, TLSError.internal_error );
375
- }
376
-
377
- /**
378
- * two unimplemented functions
379
- */
380
- private function parseClientKeyExchange( rec:ByteArray ) : void {
381
- throw new TLSError( "ClientKeyExchange is currently unimplemented!", TLSError.internal_error );
382
- }
383
-
384
- private function parseServerKeyExchange( rec:ByteArray ) : void {
385
- throw new TLSError( "ServerKeyExchange is currently unimplemented!", TLSError.internal_error );
386
- }
387
-
388
- /**
389
- * Test the server's Finished message for validity against the data we know about. Only slightly rewritten. BP
390
- */
391
- private function verifyHandshake( rec:ByteArray):void {
392
- // Get the Finished message
393
- var verifyData:ByteArray = new ByteArray;
394
- // This, in the vain hope that noboby is using SSL 2 anymore
395
- if (_securityParameters.version == SSLSecurityParameters.PROTOCOL_VERSION) {
396
- rec.readBytes(verifyData, 0, 36); // length should be (in fact, better be) 16 + 20 (md5-size + sha1-size)
397
- } else { // presuming TLS
398
- rec.readBytes(verifyData, 0, 12);
399
- }
400
-
401
- var data:ByteArray = _securityParameters.computeVerifyData(1-_entity, _handshakePayloads);
402
-
403
- if (ArrayUtil.equals(verifyData, data)) {
404
- _state = STATE_READY;
405
- dispatchEvent(new TLSEvent(TLSEvent.READY));
406
- } else {
407
- throw new TLSError("Invalid Finished mac.", TLSError.bad_record_mac);
408
- }
409
- }
410
-
411
- // enforceClient/enforceServer removed in favor of state-driven function maps
412
-
413
- /**
414
- * Handle a HANDSHAKE_HELLO
415
- */
416
- private function parseHandshakeHello( rec:ByteArray ) : void {
417
- if (_state != STATE_READY) {
418
- trace("Received an HELLO_REQUEST before being in state READY. ignoring.");
419
- return;
420
- }
421
- _handshakePayloads = new ByteArray;
422
- startHandshake();
423
- }
424
-
425
- /**
426
- * Handle a HANDSHAKE_CLIENT_KEY_EXCHANGE
427
- */
428
- private function parseHandshakeClientKeyExchange(rec:ByteArray):void {
429
- if (_securityParameters.useRSA) {
430
- // skip 2 bytes for length.
431
- var len:uint = rec.readShort();
432
- var cipher:ByteArray = new ByteArray;
433
- rec.readBytes(cipher, 0, len);
434
- var preMasterSecret:ByteArray = new ByteArray;
435
- _config.privateKey.decrypt(cipher, preMasterSecret, len);
436
- _securityParameters.setPreMasterSecret(preMasterSecret);
437
-
438
- // now is a good time to get our pending states
439
- var o:Object = _securityParameters.getConnectionStates();
440
- _pendingReadState = o.read;
441
- _pendingWriteState = o.write;
442
-
443
- } else {
444
- throw new TLSError("parseHandshakeClientKeyExchange not implemented for DH modes.", TLSError.internal_error);
445
- }
446
-
447
- }
448
-
449
- /**
450
- * Handle HANDSHAKE_SERVER_HELLO - client-side
451
- */
452
- private function parseHandshakeServerHello( rec:IDataInput ) : void {
453
-
454
- var ver:uint = rec.readShort();
455
- if (ver != _securityParameters.version) {
456
- throw new TLSError("Unsupported TLS version: "+ver.toString(16), TLSError.protocol_version);
457
- }
458
- var random:ByteArray = new ByteArray;
459
- rec.readBytes(random, 0, 32);
460
- var session_length:uint = rec.readByte();
461
- var session:ByteArray = new ByteArray;
462
- if (session_length > 0) {
463
- // some implementations don't assign a session ID
464
- rec.readBytes(session, 0, session_length);
465
- }
466
-
467
- _securityParameters.setCipher(rec.readShort());
468
- _securityParameters.setCompression(rec.readByte());
469
- _securityParameters.setServerRandom(random);
470
- }
471
-
472
- /**
473
- * Handle HANDSHAKE_CLIENT_HELLO - server side
474
- */
475
- private function parseHandshakeClientHello( rec:IDataInput ) : void {
476
- var ret:Object;
477
- var ver:uint = rec.readShort();
478
- if (ver != _securityParameters.version) {
479
- throw new TLSError("Unsupported TLS version: "+ver.toString(16), TLSError.protocol_version);
480
- }
481
-
482
- var random:ByteArray = new ByteArray;
483
- rec.readBytes(random, 0, 32);
484
- var session_length:uint = rec.readByte();
485
- var session:ByteArray = new ByteArray;
486
- if (session_length > 0) {
487
- // some implementations don't assign a session ID
488
- rec.readBytes(session, 0, session_length);
489
- }
490
- var suites:Array = [];
491
-
492
- var suites_length:uint = rec.readShort();
493
- for (var i:uint=0;i<suites_length/2;i++) {
494
- suites.push(rec.readShort());
495
- }
496
-
497
- var compressions:Array = [];
498
-
499
- var comp_length:uint = rec.readByte();
500
- for (i=0;i<comp_length;i++) {
501
- compressions.push(rec.readByte());
502
- }
503
-
504
- ret = {random:random, session:session, suites:suites, compressions:compressions};
505
-
506
- var sofar:uint = 2+32+1+session_length+2+suites_length+1+comp_length;
507
- var extensions:Array = [];
508
- if (sofar<length) {
509
- // we have extensions. great.
510
- var ext_total_length:uint = rec.readShort();
511
- while (ext_total_length>0) {
512
- var ext_type:uint = rec.readShort();
513
- var ext_length:uint = rec.readShort();
514
- var ext_data:ByteArray = new ByteArray;
515
- rec.readBytes(ext_data, 0, ext_length);
516
- ext_total_length -= 4+ext_length;
517
- extensions.push({type:ext_type, length:ext_length, data:ext_data});
518
- }
519
- }
520
- ret.ext = extensions;
521
-
522
- sendServerHello(ret);
523
- sendCertificate();
524
- // TODO: Modify to handle case of requesting a certificate from the client, for "client authentication",
525
- // and testing purposes, will probably never actually need it.
526
- sendServerHelloDone();
527
- }
528
-
529
- private function sendClientHello():void {
530
- var rec:ByteArray = new ByteArray;
531
- // version - modified to support version attribute from ISecurityParameters
532
- rec.writeShort(_securityParameters.version);
533
- // random
534
- var prng:Random = new Random;
535
- var clientRandom:ByteArray = new ByteArray;
536
- prng.nextBytes(clientRandom, 32);
537
- _securityParameters.setClientRandom(clientRandom);
538
- rec.writeBytes(clientRandom,0,32);
539
- // session
540
- rec.writeByte(32);
541
- prng.nextBytes(rec, 32);
542
- // Cipher suites
543
- var cs:Array = _config.cipherSuites;
544
- rec.writeShort(2* cs.length);
545
- for (var i:int=0;i<cs.length;i++) {
546
- rec.writeShort(cs[i]);
547
- }
548
- // Compression
549
- cs = _config.compressions;
550
- rec.writeByte(cs.length);
551
- for (i=0;i<cs.length;i++) {
552
- rec.writeByte(cs[i]);
553
- }
554
- // no extensions, yet.
555
- rec.position = 0;
556
- sendHandshake(HANDSHAKE_CLIENT_HELLO, rec.length, rec);
557
- }
558
-
559
- private function findMatch(a1:Array, a2:Array):int {
560
- for (var i:int=0;i<a1.length;i++) {
561
- var e:uint = a1[i];
562
- if (a2.indexOf(e)>-1) {
563
- return e;
564
- }
565
- }
566
- return -1;
567
- }
568
-
569
- private function sendServerHello(v:Object):void {
570
- var cipher:int = findMatch(_config.cipherSuites, v.suites);
571
- if (cipher == -1) {
572
- throw new TLSError("No compatible cipher found.", TLSError.handshake_failure);
573
- }
574
- _securityParameters.setCipher(cipher);
575
-
576
- var comp:int = findMatch(_config.compressions, v.compressions);
577
- if (comp == 01) {
578
- throw new TLSError("No compatible compression method found.", TLSError.handshake_failure);
579
- }
580
- _securityParameters.setCompression(comp);
581
- _securityParameters.setClientRandom(v.random);
582
-
583
-
584
- var rec:ByteArray = new ByteArray;
585
- rec.writeShort(_securityParameters.version);
586
- var prng:Random = new Random;
587
- var serverRandom:ByteArray = new ByteArray;
588
- prng.nextBytes(serverRandom, 32);
589
- _securityParameters.setServerRandom(serverRandom);
590
- rec.writeBytes(serverRandom,0,32);
591
- // session
592
- rec.writeByte(32);
593
- prng.nextBytes(rec, 32);
594
- // Cipher suite
595
- rec.writeShort(v.suites[0]);
596
- // Compression
597
- rec.writeByte(v.compressions[0]);
598
- rec.position = 0;
599
- sendHandshake(HANDSHAKE_SERVER_HELLO, rec.length, rec);
600
- }
601
-
602
- private var sendClientCert:Boolean = false;
603
- private function setStateRespondWithCertificate( r:ByteArray = null) : void {
604
- sendClientCert = true;
605
- }
606
-
607
- private function sendCertificate( r:ByteArray = null ):void {
608
- var cert:ByteArray = _config.certificate;
609
- var len:uint;
610
- var len2:uint;
611
- var rec:ByteArray = new ByteArray;
612
- // Look for a certficate chain, if we have one, send it, if we don't, send an empty record.
613
- if (cert != null) {
614
- len = cert.length;
615
- len2 = cert.length + 3;
616
- rec.writeByte(len2>>16);
617
- rec.writeShort(len2&65535);
618
- rec.writeByte(len>>16);
619
- rec.writeShort(len&65535);
620
- rec.writeBytes(cert);
621
- } else {
622
- rec.writeShort( 0 );
623
- rec.writeByte( 0 );
624
- }
625
- rec.position = 0;
626
- sendHandshake(HANDSHAKE_CERTIFICATE, rec.length, rec);
627
- }
628
-
629
- private function sendCertificateVerify():void {
630
- var rec:ByteArray = new ByteArray();
631
- // Encrypt the handshake payloads here
632
- var data:ByteArray = _securityParameters.computeCertificateVerify(_entity, _handshakePayloads);
633
- data.position=0;
634
- sendHandshake(HANDSHAKE_CERTIFICATE_VERIFY, data.length, data);
635
- }
636
-
637
- private function sendServerHelloDone():void {
638
- var rec:ByteArray = new ByteArray;
639
- sendHandshake(HANDSHAKE_HELLO_DONE, rec.length, rec);
640
- }
641
-
642
- private function sendClientKeyExchange():void {
643
- if (_securityParameters.useRSA) {
644
- var p:ByteArray = new ByteArray;
645
- p.writeShort(_securityParameters.version);
646
- var prng:Random = new Random;
647
- prng.nextBytes(p, 46);
648
- p.position = 0;
649
-
650
- var preMasterSecret:ByteArray = new ByteArray;
651
- preMasterSecret.writeBytes(p, 0, p.length);
652
- preMasterSecret.position = 0;
653
- _securityParameters.setPreMasterSecret(preMasterSecret);
654
-
655
- var enc_key:ByteArray = new ByteArray;
656
- _otherCertificate.getPublicKey().encrypt(preMasterSecret, enc_key, preMasterSecret.length);
657
-
658
- enc_key.position = 0;
659
- var rec:ByteArray = new ByteArray;
660
-
661
- // TLS requires the size of the premaster key be sent BUT
662
- // SSL 3.0 does not
663
- if (_securityParameters.version > 0x0300) {
664
- rec.writeShort(enc_key.length);
665
- }
666
- rec.writeBytes(enc_key, 0, enc_key.length);
667
-
668
- rec.position=0;
669
-
670
- sendHandshake(HANDSHAKE_CLIENT_KEY_EXCHANGE, rec.length, rec);
671
-
672
- // now is a good time to get our pending states
673
- var o:Object = _securityParameters.getConnectionStates();
674
- _pendingReadState = o.read;
675
- _pendingWriteState = o.write;
676
-
677
- } else {
678
- throw new TLSError("Non-RSA Client Key Exchange not implemented.", TLSError.internal_error);
679
- }
680
- }
681
- private function sendFinished():void {
682
- var data:ByteArray = _securityParameters.computeVerifyData(_entity, _handshakePayloads);
683
- data.position=0;
684
- sendHandshake(HANDSHAKE_FINISHED, data.length, data);
685
- }
686
-
687
- private function sendHandshake(type:uint, len:uint, payload:IDataInput):void {
688
- var rec:ByteArray = new ByteArray;
689
- rec.writeByte(type);
690
- rec.writeByte(0);
691
- rec.writeShort(len);
692
- payload.readBytes(rec, rec.position, len);
693
- _handshakePayloads.writeBytes(rec, 0, rec.length);
694
- sendRecord(PROTOCOL_HANDSHAKE, rec);
695
- }
696
-
697
- private function sendChangeCipherSpec():void {
698
- var rec:ByteArray = new ByteArray;
699
- rec[0] = 1;
700
- sendRecord(PROTOCOL_CHANGE_CIPHER_SPEC, rec);
701
-
702
- // right after, switch the cipher for writing.
703
- _currentWriteState = _pendingWriteState;
704
- _pendingWriteState = null;
705
- }
706
-
707
- public function sendApplicationData(data:ByteArray, offset:uint=0, length:uint=0):void {
708
- var rec:ByteArray = new ByteArray;
709
- var len:uint = length;
710
- // BIG FAT WARNING: Patch from Arlen Cuss ALA As3crypto group on Google code.
711
- // This addresses data overflow issues when the packet size hits the max length boundary.
712
- if (len == 0) len = data.length;
713
- while (len>16384) {
714
- rec.position = 0;
715
- rec.writeBytes(data, offset, 16384);
716
- rec.position = 0;
717
- sendRecord(PROTOCOL_APPLICATION_DATA, rec);
718
- offset += 16384;
719
- len -= 16384;
720
- }
721
- rec.position = 0;
722
- rec.writeBytes(data, offset, len);
723
- // trace("Data I'm sending..." + Hex.fromArray( data ));
724
- rec.position = 0;
725
- sendRecord(PROTOCOL_APPLICATION_DATA, rec);
726
- }
727
- private function sendRecord(type:uint, payload:ByteArray):void {
728
- // encrypt
729
- payload = _currentWriteState.encrypt(type, payload);
730
-
731
- _oStream.writeByte(type);
732
- _oStream.writeShort(_securityParameters.version);
733
- _oStream.writeShort(payload.length);
734
- _oStream.writeBytes(payload, 0, payload.length);
735
-
736
- scheduleWrite();
737
- }
738
-
739
- private var _writeScheduler:uint;
740
- private function scheduleWrite():void {
741
- if (_writeScheduler!=0) return;
742
- _writeScheduler = setTimeout(commitWrite, 0);
743
- }
744
- private function commitWrite():void {
745
- clearTimeout(_writeScheduler);
746
- _writeScheduler = 0;
747
- if (_state != STATE_CLOSED) {
748
- dispatchEvent(new ProgressEvent(ProgressEvent.SOCKET_DATA));
749
- }
750
- }
751
-
752
- private function sendClientAck( rec:ByteArray ):void {
753
- if ( _handshakeCanContinue ) {
754
- // If I have a pending cert request, send it
755
- if (sendClientCert)
756
- sendCertificate();
757
- // send a client key exchange
758
- sendClientKeyExchange();
759
- // Send the certificate verify, if we have one
760
- if (_config.certificate != null)
761
- sendCertificateVerify();
762
- // send a change cipher spec
763
- sendChangeCipherSpec();
764
- // send a finished
765
- sendFinished();
766
- }
767
- }
768
-
769
- /**
770
- * Vaguely gross function that parses a RSA key out of a certificate.
771
- *
772
- * As long as that certificate looks just the way we expect it to.
773
- *
774
- */
775
- private function loadCertificates( rec:ByteArray ):void {
776
- var tmp:uint = rec.readByte();
777
- var certs_len:uint = (tmp<<16) | rec.readShort();
778
- var certs:Array = [];
779
-
780
- while (certs_len>0) {
781
- tmp = rec.readByte();
782
- var cert_len:uint = (tmp<<16) | rec.readShort();
783
- var cert:ByteArray = new ByteArray;
784
- rec.readBytes(cert, 0, cert_len);
785
- certs.push(cert);
786
- certs_len -= 3 + cert_len;
787
- }
788
-
789
- var firstCert:X509Certificate = null;
790
- for (var i:int=0;i<certs.length;i++) {
791
- var x509:X509Certificate = new X509Certificate(certs[i]);
792
- _store.addCertificate(x509);
793
- if (firstCert==null) {
794
- firstCert = x509;
795
- }
796
- }
797
-
798
-
799
- // Test first for trust override parameters
800
- // This nice trust override stuff comes from Joey Parrish via As3crypto forums
801
- var certTrusted:Boolean;
802
- if (_config.trustAllCertificates) {
803
- certTrusted = true; // Blatantly trust everything
804
- } else if (_config.trustSelfSignedCertificates ) {
805
- // Self-signed certs
806
- certTrusted = firstCert.isSelfSigned(new Date);
807
- } else {
808
- // Certs with a signer in the CA store - realistically, I should setup an event chain to handle this
809
- certTrusted = firstCert.isSigned(_store, _config.CAStore );
810
- }
811
-
812
- // Good so far
813
- if (certTrusted) {
814
- // ok, that's encouraging. now for the hostname match.
815
- if (_otherIdentity==null || _config.ignoreCommonNameMismatch ) {
816
- // we don't care who we're talking with. groovy.
817
- _otherCertificate = firstCert;
818
- } else {
819
- // use regex to handle wildcard certs
820
- var commonName:String = firstCert.getCommonName();
821
- // replace all regex special characters with escaped version, except for asterisk
822
- // replace the asterisk with a regex sequence to match one or more non-dot characters
823
- var commonNameRegex:RegExp = new RegExp( commonName.replace(/[\^\\\-$.[\]|()?+{}]/g, "\\$&").replace(/\*/g, "[^.]+"), "gi");
824
- if (commonNameRegex.exec(_otherIdentity)) {
825
- _otherCertificate = firstCert;
826
- } else {
827
- if (_config.promptUserForAcceptCert ) {
828
- _handshakeCanContinue = false;
829
- dispatchEvent( new TLSEvent( TLSEvent.PROMPT_ACCEPT_CERT ));
830
- } else {
831
- throw new TLSError("Invalid common name: "+firstCert.getCommonName()+", expected "+_otherIdentity, TLSError.bad_certificate);
832
- }
833
- }
834
- }
835
-
836
- } else {
837
- // Let's ask the user if we can accept this cert. I'm not certain of the behaviour in case of timeouts,
838
- // so I probably need to handle the case by killing and restarting the connection rather than continuing if it becomes
839
- // an issue. We shall see. BP
840
- if (_config.promptUserForAcceptCert) {
841
- _handshakeCanContinue = false;
842
- dispatchEvent( new TLSEvent( TLSEvent.PROMPT_ACCEPT_CERT ));
843
- } else {
844
- // Cannot continue, die.
845
- throw new TLSError("Cannot verify certificate", TLSError.bad_certificate);
846
- }
847
- }
848
- }
849
-
850
- // Accept the peer cert, and keep going
851
- public function acceptPeerCertificate() : void {
852
- _handshakeCanContinue = true;
853
- sendClientAck( null );
854
- }
855
-
856
- // Step off biotch! No trust for you!
857
- public function rejectPeerCertificate() : void {
858
- throw new TLSError("Peer certificate not accepted!", TLSError.bad_certificate);
859
- }
860
-
861
-
862
- private function parseAlert(p:ByteArray):void {
863
- //throw new Error("Alert not implemented.");
864
- // 7.2
865
- trace("GOT ALERT! type="+p[1]);
866
- close();
867
- }
868
- private function parseChangeCipherSpec(p:ByteArray):void {
869
- p.readUnsignedByte();
870
- if (_pendingReadState==null) {
871
- throw new TLSError("Not ready to Change Cipher Spec, damnit.", TLSError.unexpected_message);
872
- }
873
- _currentReadState = _pendingReadState;
874
- _pendingReadState = null;
875
- // 7.1
876
- }
877
- private function parseApplicationData(p:ByteArray):void {
878
- if (_state != STATE_READY) {
879
- throw new TLSError("Too soon for data!", TLSError.unexpected_message);
880
- return;
881
- }
882
- dispatchEvent(new TLSEvent(TLSEvent.DATA, p));
883
- }
884
-
885
- private function handleTLSError(e:TLSError):void {
886
- // basic rules to keep things simple:
887
- // - Make a good faith attempt at notifying peers
888
- // - TLSErrors are always fatal.
889
- // BP: Meh...not always. Common Name mismatches appear to be common on servers. Instead of closing, let's pause, and ask for confirmation
890
- // before we tear the connection down.
891
-
892
- close(e);
893
- }
894
- }
895
- }