aboutsummaryrefslogtreecommitdiffstats
path: root/signaling-server/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/SSLSecurityParameters.as
diff options
context:
space:
mode:
Diffstat (limited to 'signaling-server/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/SSLSecurityParameters.as')
-rwxr-xr-xsignaling-server/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/SSLSecurityParameters.as340
1 files changed, 340 insertions, 0 deletions
diff --git a/signaling-server/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/SSLSecurityParameters.as b/signaling-server/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/SSLSecurityParameters.as
new file mode 100755
index 0000000..3549461
--- /dev/null
+++ b/signaling-server/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/SSLSecurityParameters.as
@@ -0,0 +1,340 @@
+/**
+ * TLSSecurityParameters
+ *
+ * This class encapsulates all the security parameters that get negotiated
+ * during the TLS handshake. It also holds all the key derivation methods.
+ * Copyright (c) 2007 Henri Torgemane
+ *
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto.tls {
+ import com.hurlant.crypto.hash.MD5;
+ import com.hurlant.crypto.hash.SHA1;
+ import com.hurlant.util.Hex;
+
+ import flash.utils.ByteArray;
+
+ public class SSLSecurityParameters implements ISecurityParameters {
+
+ // COMPRESSION
+ public static const COMPRESSION_NULL:uint = 0;
+
+ private var entity:uint; // SERVER | CLIENT
+ private var bulkCipher:uint; // BULK_CIPHER_*
+ private var cipherType:uint; // STREAM_CIPHER | BLOCK_CIPHER
+ private var keySize:uint;
+ private var keyMaterialLength:uint;
+ private var keyBlock:ByteArray;
+ private var IVSize:uint;
+ private var MAC_length:uint;
+ private var macAlgorithm:uint; // MAC_*
+ private var hashSize:uint;
+ private var compression:uint; // COMPRESSION_NULL
+ private var masterSecret:ByteArray; // 48 bytes
+ private var clientRandom:ByteArray; // 32 bytes
+ private var serverRandom:ByteArray; // 32 bytes
+ private var pad_1:ByteArray; // varies
+ private var pad_2:ByteArray; // varies
+ private var ignoreCNMismatch:Boolean = true;
+ private var trustAllCerts:Boolean = false;
+ private var trustSelfSigned:Boolean = false;
+ public static const PROTOCOL_VERSION:uint = 0x0300;
+
+ // not strictly speaking part of this, but yeah.
+ public var keyExchange:uint;
+
+ public function get version() : uint {
+ return PROTOCOL_VERSION;
+ }
+ public function SSLSecurityParameters(entity:uint, localCert:ByteArray = null, localKey:ByteArray = null) {
+ this.entity = entity;
+ reset();
+ }
+
+ public function reset():void {
+ bulkCipher = BulkCiphers.NULL;
+ cipherType = BulkCiphers.BLOCK_CIPHER;
+ macAlgorithm = MACs.NULL;
+ compression = COMPRESSION_NULL;
+ masterSecret = null;
+ }
+
+ public function getBulkCipher():uint {
+ return bulkCipher;
+ }
+ public function getCipherType():uint {
+ return cipherType;
+ }
+ public function getMacAlgorithm():uint {
+ return macAlgorithm;
+ }
+
+ public function setCipher(cipher:uint):void {
+ bulkCipher = CipherSuites.getBulkCipher(cipher);
+ cipherType = BulkCiphers.getType(bulkCipher);
+ keySize = BulkCiphers.getExpandedKeyBytes(bulkCipher); // 8
+ keyMaterialLength = BulkCiphers.getKeyBytes(bulkCipher); // 5
+ IVSize = BulkCiphers.getIVSize(bulkCipher);
+
+
+ keyExchange = CipherSuites.getKeyExchange(cipher);
+
+ macAlgorithm = CipherSuites.getMac(cipher);
+ hashSize = MACs.getHashSize(macAlgorithm);
+ pad_1 = new ByteArray();
+ pad_2 = new ByteArray();
+ for (var x:int = 0; x < 48; x++) {
+ pad_1.writeByte(0x36);
+ pad_2.writeByte(0x5c);
+ }
+ }
+ public function setCompression(algo:uint):void {
+ compression = algo;
+ }
+
+ public function setPreMasterSecret(secret:ByteArray):void {
+ /* Warning! Following code may cause madness
+ Tread not here, unless ye be men of valor.
+
+ ***** Official Prophylactic Comment ******
+ (to protect the unwary...this code actually works, that's all you need to know)
+
+ This does two things, computes the master secret, and generates the keyBlock
+
+
+ To compute the master_secret, the following algorithm is used.
+ for SSL 3, this means
+ master = MD5( premaster + SHA1('A' + premaster + client_random + server_random ) ) +
+ MD5( premaster + SHA1('BB' + premaster + client_random + server_random ) ) +
+ MD5( premaster + SHA1('CCC' + premaster + client_random + server_random ) )
+ */
+ var tempHashA:ByteArray = new ByteArray(); // temporary hash, gets reused a lot
+ var tempHashB:ByteArray = new ByteArray(); // temporary hash, gets reused a lot
+
+ var shaHash:ByteArray;
+ var mdHash:ByteArray;
+
+ var i:int;
+ var j:int;
+
+ var sha:SHA1 = new SHA1();
+ var md:MD5 = new MD5();
+
+ var k:ByteArray = new ByteArray();
+
+ k.writeBytes(secret);
+ k.writeBytes(clientRandom);
+ k.writeBytes(serverRandom);
+
+ masterSecret = new ByteArray();
+ var pad_char:uint = 0x41;
+
+ for ( i = 0; i < 3; i++) {
+ // SHA portion
+ tempHashA.position = 0;
+
+ for ( j = 0; j < i + 1; j++) {
+ tempHashA.writeByte(pad_char);
+ }
+ pad_char++;
+
+ tempHashA.writeBytes(k);
+ shaHash = sha.hash(tempHashA);
+
+ // MD5 portion
+ tempHashB.position = 0;
+ tempHashB.writeBytes(secret);
+ tempHashB.writeBytes(shaHash);
+ mdHash = md.hash(tempHashB);
+
+ // copy into my key
+ masterSecret.writeBytes(mdHash);
+ }
+
+ // *************** END MASTER SECRET **************
+
+ // More prophylactic comments
+ // *************** START KEY BLOCK ****************
+
+ // So here, I'm setting up the keyBlock array that I will derive MACs, keys, and IVs from.
+ // Rebuild k (hash seed)
+
+ k.position = 0;
+ k.writeBytes(masterSecret);
+ k.writeBytes(serverRandom);
+ k.writeBytes(clientRandom);
+
+ keyBlock = new ByteArray();
+
+ tempHashA = new ByteArray();
+ tempHashB = new ByteArray();
+ // now for 16 iterations to get 256 bytes (16 * 16), better to have more than not enough
+ pad_char = 0x41;
+ for ( i = 0; i < 16; i++) {
+ tempHashA.position = 0;
+
+ for ( j = 0; j < i + 1; j++) {
+ tempHashA.writeByte(pad_char);
+ }
+ pad_char++;
+ tempHashA.writeBytes(k);
+ shaHash = sha.hash(tempHashA);
+
+ tempHashB.position = 0;
+ tempHashB.writeBytes(masterSecret);
+ tempHashB.writeBytes(shaHash, 0);
+ mdHash = md.hash(tempHashB);
+
+ keyBlock.writeBytes(mdHash);
+ }
+ }
+
+ public function setClientRandom(secret:ByteArray):void {
+ clientRandom = secret;
+ }
+ public function setServerRandom(secret:ByteArray):void {
+ serverRandom = secret;
+ }
+
+ public function get useRSA():Boolean {
+ return KeyExchanges.useRSA(keyExchange);
+ }
+
+ // This is the Finished message
+ // if you value your sanity, stay away...far away
+ public function computeVerifyData(side:uint, handshakeMessages:ByteArray):ByteArray {
+ // for SSL 3.0, this consists of
+ // finished = md5( masterSecret + pad2 + md5( handshake + sender + masterSecret + pad1 ) ) +
+ // sha1( masterSecret + pad2 + sha1( handshake + sender + masterSecret + pad1 ) )
+
+ // trace("Handshake messages: " + Hex.fromArray(handshakeMessages));
+ var sha:SHA1 = new SHA1();
+ var md:MD5 = new MD5();
+ var k:ByteArray = new ByteArray(); // handshake + sender + masterSecret + pad1
+ var j:ByteArray = new ByteArray(); // masterSecret + pad2 + k
+
+ var innerKey:ByteArray;
+ var outerKey:ByteArray = new ByteArray();
+
+ var hashSha:ByteArray;
+ var hashMD:ByteArray;
+
+ var sideBytes:ByteArray = new ByteArray();
+ if (side == TLSEngine.CLIENT) {
+ sideBytes.writeUnsignedInt(0x434C4E54);
+ } else {
+ sideBytes.writeUnsignedInt(0x53525652);
+ }
+
+ // Do the SHA1 part of the routine first
+ masterSecret.position = 0;
+ k.writeBytes(handshakeMessages);
+ k.writeBytes(sideBytes);
+ k.writeBytes(masterSecret);
+ k.writeBytes(pad_1, 0, 40); // limited to 40 chars for SHA1
+
+ innerKey = sha.hash(k);
+ // trace("Inner SHA Key: " + Hex.fromArray(innerKey));
+
+ j.writeBytes(masterSecret);
+ j.writeBytes(pad_2, 0, 40); // limited to 40 chars for SHA1
+ j.writeBytes(innerKey);
+
+ hashSha = sha.hash(j);
+ // trace("Outer SHA Key: " + Hex.fromArray(hashSha));
+
+ // Rebuild k for MD5
+ k = new ByteArray();
+
+ k.writeBytes(handshakeMessages);
+ k.writeBytes(sideBytes);
+ k.writeBytes(masterSecret);
+ k.writeBytes(pad_1); // Take the whole length of pad_1 & pad_2 for MD5
+
+ innerKey = md.hash(k);
+ // trace("Inner MD5 Key: " + Hex.fromArray(innerKey));
+
+ j = new ByteArray();
+ j.writeBytes(masterSecret);
+ j.writeBytes(pad_2); // see above re: 48 byte pad
+ j.writeBytes(innerKey);
+
+ hashMD = md.hash(j);
+ // trace("Outer MD5 Key: " + Hex.fromArray(hashMD));
+
+ outerKey.writeBytes(hashMD, 0, hashMD.length);
+ outerKey.writeBytes(hashSha, 0, hashSha.length);
+ var out:String = Hex.fromArray(outerKey);
+ // trace("Finished Message: " + out);
+ outerKey.position = 0;
+
+ return outerKey;
+
+ }
+
+ public function computeCertificateVerify( side:uint, handshakeMessages:ByteArray ):ByteArray {
+ // TODO: Implement this, but I don't forsee it being necessary at this point in time, since for purposes
+ // of the override, I'm only going to use TLS
+ return null;
+ }
+
+ public function getConnectionStates():Object {
+
+ if (masterSecret != null) {
+ // so now, I have to derive the actual keys from the keyblock that I generated in setPremasterSecret.
+ // for MY purposes, I need RSA-AES 128/256 + SHA
+ // so I'm gonna have keylen = 32, minlen = 32, mac_length = 20, iv_length = 16
+ // but...I can get this data from the settings returned in the constructor when this object is
+ // It strikes me that TLS does this more elegantly...
+
+ var mac_length:int = hashSize as Number;
+ var key_length:int = keySize as Number;
+ var iv_length:int = IVSize as Number;
+
+ var client_write_MAC:ByteArray = new ByteArray();
+ var server_write_MAC:ByteArray = new ByteArray();
+ var client_write_key:ByteArray = new ByteArray();
+ var server_write_key:ByteArray = new ByteArray();
+ var client_write_IV:ByteArray = new ByteArray();
+ var server_write_IV:ByteArray = new ByteArray();
+
+ // Derive the keys from the keyblock
+ // Get the MACs first
+ keyBlock.position = 0;
+ keyBlock.readBytes(client_write_MAC, 0, mac_length);
+ keyBlock.readBytes(server_write_MAC, 0, mac_length);
+
+ // keyBlock.position is now at MAC_length * 2
+ // then get the keys
+ keyBlock.readBytes(client_write_key, 0, key_length);
+ keyBlock.readBytes(server_write_key, 0, key_length);
+
+ // keyBlock.position is now at (MAC_length * 2) + (keySize * 2)
+ // and then the IVs
+ keyBlock.readBytes(client_write_IV, 0, iv_length);
+ keyBlock.readBytes(server_write_IV, 0, iv_length);
+
+ // reset this in case it's needed, for some reason or another, but I doubt it
+ keyBlock.position = 0;
+
+ var client_write:SSLConnectionState = new SSLConnectionState(
+ bulkCipher, cipherType, macAlgorithm,
+ client_write_MAC, client_write_key, client_write_IV);
+ var server_write:SSLConnectionState = new SSLConnectionState(
+ bulkCipher, cipherType, macAlgorithm,
+ server_write_MAC, server_write_key, server_write_IV);
+
+ if (entity == TLSEngine.CLIENT) {
+ return {read:server_write, write:client_write};
+ } else {
+ return {read:client_write, write:server_write};
+ }
+
+
+ } else {
+ return {read:new SSLConnectionState, write:new SSLConnectionState};
+ }
+ }
+
+ }
+} \ No newline at end of file