From b60df56157ee1fd0bd4938799bac05a62fda91a1 Mon Sep 17 00:00:00 2001 From: lookshe Date: Sat, 14 Mar 2015 20:45:20 +0100 Subject: initial commit from working version --- .../hurlant/crypto/tls/SSLSecurityParameters.as | 340 +++++++++++++++++++++ 1 file changed, 340 insertions(+) create mode 100755 signaling-server/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/SSLSecurityParameters.as (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') 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 -- cgit v1.2.3