rocket-js 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +0 -11
- data/Rakefile +33 -47
- data/lib/rocket/js.rb +0 -2
- data/lib/rocket/js/builder.rb +2 -2
- data/lib/rocket/js/cli.rb +1 -1
- data/rocket-js.gemspec +23 -80
- data/src/vendor/web-socket-js/FABridge.js +604 -0
- data/src/vendor/web-socket-js/README.txt +109 -0
- data/src/vendor/web-socket-js/WebSocketMain.swf +0 -0
- data/src/vendor/web-socket-js/WebSocketMainInsecure.zip +0 -0
- data/src/vendor/web-socket-js/flash-src/WebSocket.as +473 -0
- data/src/vendor/web-socket-js/flash-src/WebSocketMain.as +88 -0
- data/src/vendor/web-socket-js/flash-src/WebSocketMainInsecure.as +19 -0
- data/src/vendor/web-socket-js/flash-src/WebSocketStateEvent.as +32 -0
- data/src/vendor/web-socket-js/flash-src/bridge/FABridge.as +943 -0
- data/src/vendor/web-socket-js/flash-src/build.sh +10 -0
- data/src/vendor/web-socket-js/flash-src/com/adobe/net/proxies/RFC2817Socket.as +204 -0
- data/src/vendor/web-socket-js/flash-src/com/gsolo/encryption/MD5.as +375 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/Crypto.as +287 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/cert/MozillaRootCertificates.as +3235 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/cert/X509Certificate.as +218 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/cert/X509CertificateCollection.as +57 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/HMAC.as +82 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/IHMAC.as +27 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/IHash.as +21 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/MAC.as +137 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/MD2.as +124 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/MD5.as +204 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/SHA1.as +106 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/SHA224.as +28 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/SHA256.as +115 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/SHABase.as +71 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/prng/ARC4.as +90 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/prng/IPRNG.as +20 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/prng/Random.as +119 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/prng/TLSPRF.as +142 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/rsa/RSAKey.as +339 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/AESKey.as +2797 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/BlowFishKey.as +375 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/CBCMode.as +55 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/CFB8Mode.as +61 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/CFBMode.as +64 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/CTRMode.as +58 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/DESKey.as +365 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/ECBMode.as +86 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/ICipher.as +21 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/IMode.as +15 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/IPad.as +32 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/IStreamCipher.as +21 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/ISymmetricKey.as +35 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/IVMode.as +110 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/NullPad.as +34 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/OFBMode.as +52 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/PKCS5.as +44 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/SSLPad.as +44 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/SimpleIVMode.as +60 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/TLSPad.as +42 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/TripleDESKey.as +88 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/XTeaKey.as +94 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/aeskey.pl +29 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/dump.txt +2304 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/AESKeyTest.as +1220 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/ARC4Test.as +58 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/BigIntegerTest.as +39 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/BlowFishKeyTest.as +148 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/CBCModeTest.as +160 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/CFB8ModeTest.as +71 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/CFBModeTest.as +98 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/CTRModeTest.as +109 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/DESKeyTest.as +112 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/ECBModeTest.as +151 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/HMACTest.as +184 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/ITestHarness.as +20 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/MD2Test.as +56 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/MD5Test.as +58 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/OFBModeTest.as +101 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/RSAKeyTest.as +92 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/SHA1Test.as +198 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/SHA224Test.as +58 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/SHA256Test.as +60 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/TLSPRFTest.as +51 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/TestCase.as +42 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/TripleDESKeyTest.as +59 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/XTeaKeyTest.as +66 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/BulkCiphers.as +102 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/CipherSuites.as +117 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/IConnectionState.as +14 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/ISecurityParameters.as +29 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/KeyExchanges.as +24 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/MACs.as +38 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/SSLConnectionState.as +171 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/SSLEvent.as +26 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/SSLSecurityParameters.as +340 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSConfig.as +70 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSConnectionState.as +151 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSEngine.as +895 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSError.as +39 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSEvent.as +27 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSSecurityParameters.as +197 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSSocket.as +370 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSSocketEvent.as +26 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSTest.as +180 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/math/BarrettReduction.as +90 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/math/BigInteger.as +1543 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/math/ClassicReduction.as +35 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/math/IReduction.as +11 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/math/MontgomeryReduction.as +85 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/math/NullReduction.as +34 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/math/bi_internal.as +11 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/ArrayUtil.as +25 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/Base64.as +189 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/Hex.as +66 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/Memory.as +28 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/ByteString.as +43 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/DER.as +210 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/IAsn1Type.as +21 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/Integer.as +44 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/OID.as +35 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/ObjectIdentifier.as +112 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/PEM.as +118 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/PrintableString.as +49 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/Sequence.as +90 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/Set.as +27 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/Type.as +94 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/UTCTime.as +60 -0
- data/src/vendor/web-socket-js/sample.html +76 -0
- data/src/vendor/web-socket-js/swfobject.js +4 -0
- data/src/vendor/web-socket-js/web_socket.js +388 -0
- metadata +163 -30
- data/lib/rocket/js/version.rb +0 -14
- data/rocket-0.0.1.min.js +0 -45
@@ -0,0 +1,26 @@
|
|
1
|
+
/**
|
2
|
+
* SSLEvent
|
3
|
+
*
|
4
|
+
* This is used by TLSEngine to let the application layer know
|
5
|
+
* when we're ready for sending, or have received application data
|
6
|
+
* This Event was created by Bobby Parker to support SSL 3.0.
|
7
|
+
*
|
8
|
+
* See LICENSE.txt for full license information.
|
9
|
+
*/
|
10
|
+
package com.hurlant.crypto.tls {
|
11
|
+
import flash.events.Event;
|
12
|
+
import flash.utils.ByteArray;
|
13
|
+
|
14
|
+
public class SSLEvent extends Event {
|
15
|
+
|
16
|
+
static public const DATA:String = "data";
|
17
|
+
static public const READY:String = "ready";
|
18
|
+
|
19
|
+
public var data:ByteArray;
|
20
|
+
|
21
|
+
public function SSLEvent(type:String, data:ByteArray = null) {
|
22
|
+
this.data = data;
|
23
|
+
super(type, false, false);
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
@@ -0,0 +1,340 @@
|
|
1
|
+
/**
|
2
|
+
* TLSSecurityParameters
|
3
|
+
*
|
4
|
+
* This class encapsulates all the security parameters that get negotiated
|
5
|
+
* during the TLS handshake. It also holds all the key derivation methods.
|
6
|
+
* Copyright (c) 2007 Henri Torgemane
|
7
|
+
*
|
8
|
+
* See LICENSE.txt for full license information.
|
9
|
+
*/
|
10
|
+
package com.hurlant.crypto.tls {
|
11
|
+
import com.hurlant.crypto.hash.MD5;
|
12
|
+
import com.hurlant.crypto.hash.SHA1;
|
13
|
+
import com.hurlant.util.Hex;
|
14
|
+
|
15
|
+
import flash.utils.ByteArray;
|
16
|
+
|
17
|
+
public class SSLSecurityParameters implements ISecurityParameters {
|
18
|
+
|
19
|
+
// COMPRESSION
|
20
|
+
public static const COMPRESSION_NULL:uint = 0;
|
21
|
+
|
22
|
+
private var entity:uint; // SERVER | CLIENT
|
23
|
+
private var bulkCipher:uint; // BULK_CIPHER_*
|
24
|
+
private var cipherType:uint; // STREAM_CIPHER | BLOCK_CIPHER
|
25
|
+
private var keySize:uint;
|
26
|
+
private var keyMaterialLength:uint;
|
27
|
+
private var keyBlock:ByteArray;
|
28
|
+
private var IVSize:uint;
|
29
|
+
private var MAC_length:uint;
|
30
|
+
private var macAlgorithm:uint; // MAC_*
|
31
|
+
private var hashSize:uint;
|
32
|
+
private var compression:uint; // COMPRESSION_NULL
|
33
|
+
private var masterSecret:ByteArray; // 48 bytes
|
34
|
+
private var clientRandom:ByteArray; // 32 bytes
|
35
|
+
private var serverRandom:ByteArray; // 32 bytes
|
36
|
+
private var pad_1:ByteArray; // varies
|
37
|
+
private var pad_2:ByteArray; // varies
|
38
|
+
private var ignoreCNMismatch:Boolean = true;
|
39
|
+
private var trustAllCerts:Boolean = false;
|
40
|
+
private var trustSelfSigned:Boolean = false;
|
41
|
+
public static const PROTOCOL_VERSION:uint = 0x0300;
|
42
|
+
|
43
|
+
// not strictly speaking part of this, but yeah.
|
44
|
+
public var keyExchange:uint;
|
45
|
+
|
46
|
+
public function get version() : uint {
|
47
|
+
return PROTOCOL_VERSION;
|
48
|
+
}
|
49
|
+
public function SSLSecurityParameters(entity:uint, localCert:ByteArray = null, localKey:ByteArray = null) {
|
50
|
+
this.entity = entity;
|
51
|
+
reset();
|
52
|
+
}
|
53
|
+
|
54
|
+
public function reset():void {
|
55
|
+
bulkCipher = BulkCiphers.NULL;
|
56
|
+
cipherType = BulkCiphers.BLOCK_CIPHER;
|
57
|
+
macAlgorithm = MACs.NULL;
|
58
|
+
compression = COMPRESSION_NULL;
|
59
|
+
masterSecret = null;
|
60
|
+
}
|
61
|
+
|
62
|
+
public function getBulkCipher():uint {
|
63
|
+
return bulkCipher;
|
64
|
+
}
|
65
|
+
public function getCipherType():uint {
|
66
|
+
return cipherType;
|
67
|
+
}
|
68
|
+
public function getMacAlgorithm():uint {
|
69
|
+
return macAlgorithm;
|
70
|
+
}
|
71
|
+
|
72
|
+
public function setCipher(cipher:uint):void {
|
73
|
+
bulkCipher = CipherSuites.getBulkCipher(cipher);
|
74
|
+
cipherType = BulkCiphers.getType(bulkCipher);
|
75
|
+
keySize = BulkCiphers.getExpandedKeyBytes(bulkCipher); // 8
|
76
|
+
keyMaterialLength = BulkCiphers.getKeyBytes(bulkCipher); // 5
|
77
|
+
IVSize = BulkCiphers.getIVSize(bulkCipher);
|
78
|
+
|
79
|
+
|
80
|
+
keyExchange = CipherSuites.getKeyExchange(cipher);
|
81
|
+
|
82
|
+
macAlgorithm = CipherSuites.getMac(cipher);
|
83
|
+
hashSize = MACs.getHashSize(macAlgorithm);
|
84
|
+
pad_1 = new ByteArray();
|
85
|
+
pad_2 = new ByteArray();
|
86
|
+
for (var x:int = 0; x < 48; x++) {
|
87
|
+
pad_1.writeByte(0x36);
|
88
|
+
pad_2.writeByte(0x5c);
|
89
|
+
}
|
90
|
+
}
|
91
|
+
public function setCompression(algo:uint):void {
|
92
|
+
compression = algo;
|
93
|
+
}
|
94
|
+
|
95
|
+
public function setPreMasterSecret(secret:ByteArray):void {
|
96
|
+
/* Warning! Following code may cause madness
|
97
|
+
Tread not here, unless ye be men of valor.
|
98
|
+
|
99
|
+
***** Official Prophylactic Comment ******
|
100
|
+
(to protect the unwary...this code actually works, that's all you need to know)
|
101
|
+
|
102
|
+
This does two things, computes the master secret, and generates the keyBlock
|
103
|
+
|
104
|
+
|
105
|
+
To compute the master_secret, the following algorithm is used.
|
106
|
+
for SSL 3, this means
|
107
|
+
master = MD5( premaster + SHA1('A' + premaster + client_random + server_random ) ) +
|
108
|
+
MD5( premaster + SHA1('BB' + premaster + client_random + server_random ) ) +
|
109
|
+
MD5( premaster + SHA1('CCC' + premaster + client_random + server_random ) )
|
110
|
+
*/
|
111
|
+
var tempHashA:ByteArray = new ByteArray(); // temporary hash, gets reused a lot
|
112
|
+
var tempHashB:ByteArray = new ByteArray(); // temporary hash, gets reused a lot
|
113
|
+
|
114
|
+
var shaHash:ByteArray;
|
115
|
+
var mdHash:ByteArray;
|
116
|
+
|
117
|
+
var i:int;
|
118
|
+
var j:int;
|
119
|
+
|
120
|
+
var sha:SHA1 = new SHA1();
|
121
|
+
var md:MD5 = new MD5();
|
122
|
+
|
123
|
+
var k:ByteArray = new ByteArray();
|
124
|
+
|
125
|
+
k.writeBytes(secret);
|
126
|
+
k.writeBytes(clientRandom);
|
127
|
+
k.writeBytes(serverRandom);
|
128
|
+
|
129
|
+
masterSecret = new ByteArray();
|
130
|
+
var pad_char:uint = 0x41;
|
131
|
+
|
132
|
+
for ( i = 0; i < 3; i++) {
|
133
|
+
// SHA portion
|
134
|
+
tempHashA.position = 0;
|
135
|
+
|
136
|
+
for ( j = 0; j < i + 1; j++) {
|
137
|
+
tempHashA.writeByte(pad_char);
|
138
|
+
}
|
139
|
+
pad_char++;
|
140
|
+
|
141
|
+
tempHashA.writeBytes(k);
|
142
|
+
shaHash = sha.hash(tempHashA);
|
143
|
+
|
144
|
+
// MD5 portion
|
145
|
+
tempHashB.position = 0;
|
146
|
+
tempHashB.writeBytes(secret);
|
147
|
+
tempHashB.writeBytes(shaHash);
|
148
|
+
mdHash = md.hash(tempHashB);
|
149
|
+
|
150
|
+
// copy into my key
|
151
|
+
masterSecret.writeBytes(mdHash);
|
152
|
+
}
|
153
|
+
|
154
|
+
// *************** END MASTER SECRET **************
|
155
|
+
|
156
|
+
// More prophylactic comments
|
157
|
+
// *************** START KEY BLOCK ****************
|
158
|
+
|
159
|
+
// So here, I'm setting up the keyBlock array that I will derive MACs, keys, and IVs from.
|
160
|
+
// Rebuild k (hash seed)
|
161
|
+
|
162
|
+
k.position = 0;
|
163
|
+
k.writeBytes(masterSecret);
|
164
|
+
k.writeBytes(serverRandom);
|
165
|
+
k.writeBytes(clientRandom);
|
166
|
+
|
167
|
+
keyBlock = new ByteArray();
|
168
|
+
|
169
|
+
tempHashA = new ByteArray();
|
170
|
+
tempHashB = new ByteArray();
|
171
|
+
// now for 16 iterations to get 256 bytes (16 * 16), better to have more than not enough
|
172
|
+
pad_char = 0x41;
|
173
|
+
for ( i = 0; i < 16; i++) {
|
174
|
+
tempHashA.position = 0;
|
175
|
+
|
176
|
+
for ( j = 0; j < i + 1; j++) {
|
177
|
+
tempHashA.writeByte(pad_char);
|
178
|
+
}
|
179
|
+
pad_char++;
|
180
|
+
tempHashA.writeBytes(k);
|
181
|
+
shaHash = sha.hash(tempHashA);
|
182
|
+
|
183
|
+
tempHashB.position = 0;
|
184
|
+
tempHashB.writeBytes(masterSecret);
|
185
|
+
tempHashB.writeBytes(shaHash, 0);
|
186
|
+
mdHash = md.hash(tempHashB);
|
187
|
+
|
188
|
+
keyBlock.writeBytes(mdHash);
|
189
|
+
}
|
190
|
+
}
|
191
|
+
|
192
|
+
public function setClientRandom(secret:ByteArray):void {
|
193
|
+
clientRandom = secret;
|
194
|
+
}
|
195
|
+
public function setServerRandom(secret:ByteArray):void {
|
196
|
+
serverRandom = secret;
|
197
|
+
}
|
198
|
+
|
199
|
+
public function get useRSA():Boolean {
|
200
|
+
return KeyExchanges.useRSA(keyExchange);
|
201
|
+
}
|
202
|
+
|
203
|
+
// This is the Finished message
|
204
|
+
// if you value your sanity, stay away...far away
|
205
|
+
public function computeVerifyData(side:uint, handshakeMessages:ByteArray):ByteArray {
|
206
|
+
// for SSL 3.0, this consists of
|
207
|
+
// finished = md5( masterSecret + pad2 + md5( handshake + sender + masterSecret + pad1 ) ) +
|
208
|
+
// sha1( masterSecret + pad2 + sha1( handshake + sender + masterSecret + pad1 ) )
|
209
|
+
|
210
|
+
// trace("Handshake messages: " + Hex.fromArray(handshakeMessages));
|
211
|
+
var sha:SHA1 = new SHA1();
|
212
|
+
var md:MD5 = new MD5();
|
213
|
+
var k:ByteArray = new ByteArray(); // handshake + sender + masterSecret + pad1
|
214
|
+
var j:ByteArray = new ByteArray(); // masterSecret + pad2 + k
|
215
|
+
|
216
|
+
var innerKey:ByteArray;
|
217
|
+
var outerKey:ByteArray = new ByteArray();
|
218
|
+
|
219
|
+
var hashSha:ByteArray;
|
220
|
+
var hashMD:ByteArray;
|
221
|
+
|
222
|
+
var sideBytes:ByteArray = new ByteArray();
|
223
|
+
if (side == TLSEngine.CLIENT) {
|
224
|
+
sideBytes.writeUnsignedInt(0x434C4E54);
|
225
|
+
} else {
|
226
|
+
sideBytes.writeUnsignedInt(0x53525652);
|
227
|
+
}
|
228
|
+
|
229
|
+
// Do the SHA1 part of the routine first
|
230
|
+
masterSecret.position = 0;
|
231
|
+
k.writeBytes(handshakeMessages);
|
232
|
+
k.writeBytes(sideBytes);
|
233
|
+
k.writeBytes(masterSecret);
|
234
|
+
k.writeBytes(pad_1, 0, 40); // limited to 40 chars for SHA1
|
235
|
+
|
236
|
+
innerKey = sha.hash(k);
|
237
|
+
// trace("Inner SHA Key: " + Hex.fromArray(innerKey));
|
238
|
+
|
239
|
+
j.writeBytes(masterSecret);
|
240
|
+
j.writeBytes(pad_2, 0, 40); // limited to 40 chars for SHA1
|
241
|
+
j.writeBytes(innerKey);
|
242
|
+
|
243
|
+
hashSha = sha.hash(j);
|
244
|
+
// trace("Outer SHA Key: " + Hex.fromArray(hashSha));
|
245
|
+
|
246
|
+
// Rebuild k for MD5
|
247
|
+
k = new ByteArray();
|
248
|
+
|
249
|
+
k.writeBytes(handshakeMessages);
|
250
|
+
k.writeBytes(sideBytes);
|
251
|
+
k.writeBytes(masterSecret);
|
252
|
+
k.writeBytes(pad_1); // Take the whole length of pad_1 & pad_2 for MD5
|
253
|
+
|
254
|
+
innerKey = md.hash(k);
|
255
|
+
// trace("Inner MD5 Key: " + Hex.fromArray(innerKey));
|
256
|
+
|
257
|
+
j = new ByteArray();
|
258
|
+
j.writeBytes(masterSecret);
|
259
|
+
j.writeBytes(pad_2); // see above re: 48 byte pad
|
260
|
+
j.writeBytes(innerKey);
|
261
|
+
|
262
|
+
hashMD = md.hash(j);
|
263
|
+
// trace("Outer MD5 Key: " + Hex.fromArray(hashMD));
|
264
|
+
|
265
|
+
outerKey.writeBytes(hashMD, 0, hashMD.length);
|
266
|
+
outerKey.writeBytes(hashSha, 0, hashSha.length);
|
267
|
+
var out:String = Hex.fromArray(outerKey);
|
268
|
+
// trace("Finished Message: " + out);
|
269
|
+
outerKey.position = 0;
|
270
|
+
|
271
|
+
return outerKey;
|
272
|
+
|
273
|
+
}
|
274
|
+
|
275
|
+
public function computeCertificateVerify( side:uint, handshakeMessages:ByteArray ):ByteArray {
|
276
|
+
// TODO: Implement this, but I don't forsee it being necessary at this point in time, since for purposes
|
277
|
+
// of the override, I'm only going to use TLS
|
278
|
+
return null;
|
279
|
+
}
|
280
|
+
|
281
|
+
public function getConnectionStates():Object {
|
282
|
+
|
283
|
+
if (masterSecret != null) {
|
284
|
+
// so now, I have to derive the actual keys from the keyblock that I generated in setPremasterSecret.
|
285
|
+
// for MY purposes, I need RSA-AES 128/256 + SHA
|
286
|
+
// so I'm gonna have keylen = 32, minlen = 32, mac_length = 20, iv_length = 16
|
287
|
+
// but...I can get this data from the settings returned in the constructor when this object is
|
288
|
+
// It strikes me that TLS does this more elegantly...
|
289
|
+
|
290
|
+
var mac_length:int = hashSize as Number;
|
291
|
+
var key_length:int = keySize as Number;
|
292
|
+
var iv_length:int = IVSize as Number;
|
293
|
+
|
294
|
+
var client_write_MAC:ByteArray = new ByteArray();
|
295
|
+
var server_write_MAC:ByteArray = new ByteArray();
|
296
|
+
var client_write_key:ByteArray = new ByteArray();
|
297
|
+
var server_write_key:ByteArray = new ByteArray();
|
298
|
+
var client_write_IV:ByteArray = new ByteArray();
|
299
|
+
var server_write_IV:ByteArray = new ByteArray();
|
300
|
+
|
301
|
+
// Derive the keys from the keyblock
|
302
|
+
// Get the MACs first
|
303
|
+
keyBlock.position = 0;
|
304
|
+
keyBlock.readBytes(client_write_MAC, 0, mac_length);
|
305
|
+
keyBlock.readBytes(server_write_MAC, 0, mac_length);
|
306
|
+
|
307
|
+
// keyBlock.position is now at MAC_length * 2
|
308
|
+
// then get the keys
|
309
|
+
keyBlock.readBytes(client_write_key, 0, key_length);
|
310
|
+
keyBlock.readBytes(server_write_key, 0, key_length);
|
311
|
+
|
312
|
+
// keyBlock.position is now at (MAC_length * 2) + (keySize * 2)
|
313
|
+
// and then the IVs
|
314
|
+
keyBlock.readBytes(client_write_IV, 0, iv_length);
|
315
|
+
keyBlock.readBytes(server_write_IV, 0, iv_length);
|
316
|
+
|
317
|
+
// reset this in case it's needed, for some reason or another, but I doubt it
|
318
|
+
keyBlock.position = 0;
|
319
|
+
|
320
|
+
var client_write:SSLConnectionState = new SSLConnectionState(
|
321
|
+
bulkCipher, cipherType, macAlgorithm,
|
322
|
+
client_write_MAC, client_write_key, client_write_IV);
|
323
|
+
var server_write:SSLConnectionState = new SSLConnectionState(
|
324
|
+
bulkCipher, cipherType, macAlgorithm,
|
325
|
+
server_write_MAC, server_write_key, server_write_IV);
|
326
|
+
|
327
|
+
if (entity == TLSEngine.CLIENT) {
|
328
|
+
return {read:server_write, write:client_write};
|
329
|
+
} else {
|
330
|
+
return {read:client_write, write:server_write};
|
331
|
+
}
|
332
|
+
|
333
|
+
|
334
|
+
} else {
|
335
|
+
return {read:new SSLConnectionState, write:new SSLConnectionState};
|
336
|
+
}
|
337
|
+
}
|
338
|
+
|
339
|
+
}
|
340
|
+
}
|
@@ -0,0 +1,70 @@
|
|
1
|
+
/**
|
2
|
+
* TLSConfig
|
3
|
+
*
|
4
|
+
* A set of configuration parameters for use by a TLSSocket or a TLSEngine.
|
5
|
+
* Most parameters are optional and will be set to appropriate default values for most use.
|
6
|
+
*
|
7
|
+
* Copyright (c) 2007 Henri Torgemane
|
8
|
+
*
|
9
|
+
* See LICENSE.txt for full license information.
|
10
|
+
*/
|
11
|
+
package com.hurlant.crypto.tls {
|
12
|
+
import flash.utils.ByteArray;
|
13
|
+
import com.hurlant.util.der.PEM;
|
14
|
+
import com.hurlant.crypto.rsa.RSAKey;
|
15
|
+
import com.hurlant.crypto.cert.X509CertificateCollection;
|
16
|
+
import com.hurlant.crypto.cert.MozillaRootCertificates;
|
17
|
+
|
18
|
+
public class TLSConfig {
|
19
|
+
public var entity:uint; // SERVER | CLIENT
|
20
|
+
|
21
|
+
public var certificate:ByteArray;
|
22
|
+
public var privateKey:RSAKey;
|
23
|
+
|
24
|
+
public var cipherSuites:Array;
|
25
|
+
|
26
|
+
public var compressions:Array;
|
27
|
+
public var ignoreCommonNameMismatch:Boolean = false;
|
28
|
+
public var trustAllCertificates:Boolean = false;
|
29
|
+
public var trustSelfSignedCertificates:Boolean = false;
|
30
|
+
public var promptUserForAcceptCert:Boolean = false;
|
31
|
+
public var CAStore:X509CertificateCollection;
|
32
|
+
public var localKeyStore:X509CertificateCollection;
|
33
|
+
public var version:uint;
|
34
|
+
|
35
|
+
public function TLSConfig( entity:uint, cipherSuites:Array = null, compressions:Array = null,
|
36
|
+
certificate:ByteArray = null, privateKey:RSAKey = null, CAStore:X509CertificateCollection = null, ver:uint = 0x00) {
|
37
|
+
this.entity = entity;
|
38
|
+
this.cipherSuites = cipherSuites;
|
39
|
+
this.compressions = compressions;
|
40
|
+
this.certificate = certificate;
|
41
|
+
this.privateKey = privateKey;
|
42
|
+
this.CAStore = CAStore;
|
43
|
+
this.version = ver;
|
44
|
+
// default settings.
|
45
|
+
if (cipherSuites==null) {
|
46
|
+
this.cipherSuites = CipherSuites.getDefaultSuites();
|
47
|
+
}
|
48
|
+
if (compressions==null) {
|
49
|
+
this.compressions = [TLSSecurityParameters.COMPRESSION_NULL];
|
50
|
+
}
|
51
|
+
|
52
|
+
if (CAStore==null) {
|
53
|
+
this.CAStore = new MozillaRootCertificates;
|
54
|
+
}
|
55
|
+
|
56
|
+
if (ver==0x00) {
|
57
|
+
// Default to TLS
|
58
|
+
this.version = TLSSecurityParameters.PROTOCOL_VERSION;
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
public function setPEMCertificate(cert:String, key:String = null):void {
|
63
|
+
if (key == null) {
|
64
|
+
key = cert; // for folks who like to concat those two in one file.
|
65
|
+
}
|
66
|
+
certificate = PEM.readCertIntoArray(cert);
|
67
|
+
privateKey = PEM.readRSAPrivateKey(key);
|
68
|
+
}
|
69
|
+
}
|
70
|
+
}
|
@@ -0,0 +1,151 @@
|
|
1
|
+
/**
|
2
|
+
* TLSConnectionState
|
3
|
+
*
|
4
|
+
* This class encapsulates the read or write state of a TLS connection,
|
5
|
+
* and implementes the encrypting and hashing of packets.
|
6
|
+
* Copyright (c) 2007 Henri Torgemane
|
7
|
+
*
|
8
|
+
* See LICENSE.txt for full license information.
|
9
|
+
*/
|
10
|
+
package com.hurlant.crypto.tls {
|
11
|
+
import flash.utils.IDataInput;
|
12
|
+
import flash.utils.ByteArray;
|
13
|
+
import com.hurlant.crypto.hash.MD5;
|
14
|
+
import com.hurlant.crypto.hash.HMAC;
|
15
|
+
import com.hurlant.crypto.hash.IHash;
|
16
|
+
import com.hurlant.crypto.symmetric.ICipher;
|
17
|
+
import com.hurlant.crypto.symmetric.IVMode;
|
18
|
+
import com.hurlant.util.Hex;
|
19
|
+
import com.hurlant.util.ArrayUtil;
|
20
|
+
|
21
|
+
public class TLSConnectionState implements IConnectionState {
|
22
|
+
|
23
|
+
|
24
|
+
// compression state
|
25
|
+
|
26
|
+
// cipher state
|
27
|
+
private var bulkCipher:uint;
|
28
|
+
private var cipherType:uint;
|
29
|
+
private var CIPHER_key:ByteArray;
|
30
|
+
private var CIPHER_IV:ByteArray;
|
31
|
+
private var cipher:ICipher;
|
32
|
+
private var ivmode:IVMode;
|
33
|
+
|
34
|
+
// mac secret
|
35
|
+
private var macAlgorithm:uint;
|
36
|
+
private var MAC_write_secret:ByteArray;
|
37
|
+
private var hmac:HMAC;
|
38
|
+
|
39
|
+
// sequence number. uint64
|
40
|
+
private var seq_lo:uint;
|
41
|
+
private var seq_hi:uint;
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
public function TLSConnectionState(
|
46
|
+
bulkCipher:uint=0, cipherType:uint=0, macAlgorithm:uint=0,
|
47
|
+
mac:ByteArray=null, key:ByteArray=null, IV:ByteArray=null) {
|
48
|
+
this.bulkCipher = bulkCipher;
|
49
|
+
this.cipherType = cipherType;
|
50
|
+
this.macAlgorithm = macAlgorithm;
|
51
|
+
MAC_write_secret = mac;
|
52
|
+
hmac = MACs.getHMAC(macAlgorithm);
|
53
|
+
CIPHER_key = key;
|
54
|
+
CIPHER_IV = IV;
|
55
|
+
cipher = BulkCiphers.getCipher(bulkCipher, key, 0x0301);
|
56
|
+
if (cipher is IVMode) {
|
57
|
+
ivmode = cipher as IVMode;
|
58
|
+
ivmode.IV = IV;
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
public function decrypt(type:uint, length:uint, p:ByteArray):ByteArray {
|
63
|
+
// decompression is a nop.
|
64
|
+
|
65
|
+
if (cipherType == BulkCiphers.STREAM_CIPHER) {
|
66
|
+
if (bulkCipher == BulkCiphers.NULL) {
|
67
|
+
// no-op
|
68
|
+
} else {
|
69
|
+
cipher.decrypt(p);
|
70
|
+
}
|
71
|
+
} else {
|
72
|
+
// block cipher
|
73
|
+
var nextIV:ByteArray = new ByteArray;
|
74
|
+
nextIV.writeBytes(p, p.length-CIPHER_IV.length, CIPHER_IV.length);
|
75
|
+
|
76
|
+
cipher.decrypt(p);
|
77
|
+
|
78
|
+
|
79
|
+
CIPHER_IV = nextIV;
|
80
|
+
ivmode.IV = nextIV;
|
81
|
+
}
|
82
|
+
if (macAlgorithm!=MACs.NULL) {
|
83
|
+
var data:ByteArray = new ByteArray;
|
84
|
+
var len:uint = p.length - hmac.getHashSize();
|
85
|
+
data.writeUnsignedInt(seq_hi);
|
86
|
+
data.writeUnsignedInt(seq_lo);
|
87
|
+
data.writeByte(type);
|
88
|
+
data.writeShort(TLSSecurityParameters.PROTOCOL_VERSION);
|
89
|
+
data.writeShort(len);
|
90
|
+
if (len!=0) {
|
91
|
+
data.writeBytes(p, 0, len);
|
92
|
+
}
|
93
|
+
var mac:ByteArray = hmac.compute(MAC_write_secret, data);
|
94
|
+
// compare "mac" with the last X bytes of p.
|
95
|
+
var mac_received:ByteArray = new ByteArray;
|
96
|
+
mac_received.writeBytes(p, len, hmac.getHashSize());
|
97
|
+
if (ArrayUtil.equals(mac, mac_received)) {
|
98
|
+
// happy happy joy joy
|
99
|
+
} else {
|
100
|
+
throw new TLSError("Bad Mac Data", TLSError.bad_record_mac);
|
101
|
+
}
|
102
|
+
p.length = len;
|
103
|
+
p.position = 0;
|
104
|
+
}
|
105
|
+
// increment seq
|
106
|
+
seq_lo++;
|
107
|
+
if (seq_lo==0) seq_hi++;
|
108
|
+
return p;
|
109
|
+
}
|
110
|
+
public function encrypt(type:uint, p:ByteArray):ByteArray {
|
111
|
+
var mac:ByteArray = null;
|
112
|
+
if (macAlgorithm!=MACs.NULL) {
|
113
|
+
var data:ByteArray = new ByteArray;
|
114
|
+
data.writeUnsignedInt(seq_hi);
|
115
|
+
data.writeUnsignedInt(seq_lo);
|
116
|
+
data.writeByte(type);
|
117
|
+
data.writeShort(TLSSecurityParameters.PROTOCOL_VERSION);
|
118
|
+
data.writeShort(p.length);
|
119
|
+
if (p.length!=0) {
|
120
|
+
data.writeBytes(p, 0, p.length);
|
121
|
+
}
|
122
|
+
mac = hmac.compute(MAC_write_secret, data);
|
123
|
+
p.position = p.length;
|
124
|
+
p.writeBytes(mac);
|
125
|
+
}
|
126
|
+
p.position = 0;
|
127
|
+
if (cipherType == BulkCiphers.STREAM_CIPHER) {
|
128
|
+
// stream cipher
|
129
|
+
if (bulkCipher == BulkCiphers.NULL) {
|
130
|
+
// no-op
|
131
|
+
} else {
|
132
|
+
cipher.encrypt(p);
|
133
|
+
}
|
134
|
+
} else {
|
135
|
+
// block cipher
|
136
|
+
cipher.encrypt(p);
|
137
|
+
// adjust IV
|
138
|
+
var nextIV:ByteArray = new ByteArray;
|
139
|
+
nextIV.writeBytes(p, p.length-CIPHER_IV.length, CIPHER_IV.length);
|
140
|
+
CIPHER_IV = nextIV;
|
141
|
+
ivmode.IV = nextIV;
|
142
|
+
}
|
143
|
+
// increment seq
|
144
|
+
seq_lo++;
|
145
|
+
if (seq_lo==0) seq_hi++;
|
146
|
+
// compression is a nop.
|
147
|
+
return p;
|
148
|
+
}
|
149
|
+
|
150
|
+
}
|
151
|
+
}
|