rocket-js 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
- }