PageRenderTime 177ms CodeModel.GetById 61ms app.highlight 17ms RepoModel.GetById 65ms app.codeStats 1ms

/js/lib/Socket.IO-node/support/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSSecurityParameters.as

http://github.com/onedayitwillmake/RealtimeMultiplayerNodeJs
ActionScript | 197 lines | 154 code | 24 blank | 19 comment | 10 complexity | ab63d4a22710cb8f8a1e2eb7931f1aa3 MD5 | raw file
  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 * Patched by Bobby Parker (sh0rtwave@gmail.com)
  9 * 
 10 * See LICENSE.txt for full license information.
 11 */
 12package com.hurlant.crypto.tls {
 13	import com.hurlant.crypto.hash.MD5;
 14	import com.hurlant.crypto.hash.SHA1;
 15	import com.hurlant.crypto.prng.TLSPRF;
 16	import com.hurlant.util.Hex;
 17	
 18	import flash.utils.ByteArray;
 19	import com.hurlant.crypto.rsa.RSAKey;
 20	
 21	public class TLSSecurityParameters implements ISecurityParameters {
 22		
 23		// COMPRESSION
 24		public static const COMPRESSION_NULL:uint = 0;
 25		
 26		// This is probably not smart. Revise this to use all settings from TLSConfig, since this shouldn't really know about
 27		// user settings, those are best handled from the engine at a session level.
 28		public static var IGNORE_CN_MISMATCH:Boolean = true;
 29		public static var ENABLE_USER_CLIENT_CERTIFICATE:Boolean = false;
 30		public static var USER_CERTIFICATE:String;
 31		
 32		
 33		private var cert:ByteArray; // Local Cert
 34		private var key:RSAKey; // local key
 35		private var entity:uint; // SERVER | CLIENT
 36		private var bulkCipher:uint; // BULK_CIPHER_*
 37		private var cipherType:uint; // STREAM_CIPHER | BLOCK_CIPHER
 38		private var keySize:uint;
 39		private var keyMaterialLength:uint;
 40		private var IVSize:uint;
 41		private var macAlgorithm:uint; // MAC_*
 42		private var hashSize:uint;
 43		private var compression:uint; // COMPRESSION_NULL
 44		private var masterSecret:ByteArray; // 48 bytes
 45		private var clientRandom:ByteArray; // 32 bytes
 46		private var serverRandom:ByteArray; // 32 bytes
 47		private var ignoreCNMismatch:Boolean = true;
 48		private var trustAllCerts:Boolean = false;
 49		private var trustSelfSigned:Boolean = false;
 50		public static const PROTOCOL_VERSION:uint = 0x0301; 
 51		private var tlsDebug:Boolean = false;
 52
 53		
 54		// not strictly speaking part of this, but yeah.
 55		public var keyExchange:uint;
 56		public function TLSSecurityParameters(entity:uint, localCert:ByteArray = null, localKey:RSAKey = null) {
 57			this.entity = entity;
 58			reset();
 59			key = localKey;
 60			cert = localCert;
 61		}
 62		
 63		public function get version() : uint {
 64			return PROTOCOL_VERSION;
 65		}
 66		
 67		public function reset():void {
 68			bulkCipher = BulkCiphers.NULL;
 69			cipherType = BulkCiphers.BLOCK_CIPHER;
 70			macAlgorithm = MACs.NULL;
 71			compression = COMPRESSION_NULL;
 72			masterSecret = null;
 73		}
 74		
 75		public function getBulkCipher():uint {
 76			return bulkCipher;
 77		}
 78		public function getCipherType():uint {
 79			return cipherType;
 80		}
 81		public function getMacAlgorithm():uint {
 82			return macAlgorithm;
 83		}
 84		
 85		public function setCipher(cipher:uint):void {
 86			bulkCipher = CipherSuites.getBulkCipher(cipher);
 87			cipherType = BulkCiphers.getType(bulkCipher);
 88			keySize = BulkCiphers.getExpandedKeyBytes(bulkCipher);   // 8
 89			keyMaterialLength = BulkCiphers.getKeyBytes(bulkCipher); // 5
 90			IVSize = BulkCiphers.getIVSize(bulkCipher);
 91			
 92			keyExchange = CipherSuites.getKeyExchange(cipher);
 93			
 94			macAlgorithm = CipherSuites.getMac(cipher);
 95			hashSize = MACs.getHashSize(macAlgorithm);
 96		}
 97		public function setCompression(algo:uint):void {
 98			compression = algo;
 99		}
100		public function setPreMasterSecret(secret:ByteArray):void {
101			// compute master_secret
102			var seed:ByteArray = new ByteArray;
103			seed.writeBytes(clientRandom, 0, clientRandom.length);
104			seed.writeBytes(serverRandom, 0, serverRandom.length);
105			var prf:TLSPRF = new TLSPRF(secret, "master secret", seed);
106			masterSecret = new ByteArray;
107			prf.nextBytes(masterSecret, 48);
108			if (tlsDebug)
109				trace("Master Secret: " + Hex.fromArray( masterSecret, true ));
110		}
111		public function setClientRandom(secret:ByteArray):void {
112			clientRandom = secret;
113		}
114		public function setServerRandom(secret:ByteArray):void { 
115			serverRandom = secret;
116		}
117		
118		public function get useRSA():Boolean {
119			return KeyExchanges.useRSA(keyExchange);
120		}
121		
122		public function computeVerifyData(side:uint, handshakeMessages:ByteArray):ByteArray {
123			var seed:ByteArray = new ByteArray;
124			var md5:MD5 = new MD5;
125			if (tlsDebug)
126				trace("Handshake value: " + Hex.fromArray(handshakeMessages, true ));
127			seed.writeBytes(md5.hash(handshakeMessages),0,md5.getHashSize());
128			var sha:SHA1 = new SHA1;
129			seed.writeBytes(sha.hash(handshakeMessages),0,sha.getHashSize());
130			if (tlsDebug)
131				trace("Seed in: " + Hex.fromArray(seed, true ));
132			var prf:TLSPRF = new TLSPRF(masterSecret, (side==TLSEngine.CLIENT) ? "client finished" : "server finished", seed);
133			var out:ByteArray = new ByteArray;
134			prf.nextBytes(out, 12);
135			if (tlsDebug)
136				trace("Finished out: " + Hex.fromArray(out, true ));
137			out.position = 0;
138			return out;
139		}
140		
141		// client side certficate check - This is probably incorrect somehow
142		public function computeCertificateVerify( side:uint, handshakeMessages:ByteArray ):ByteArray {
143			var seed:ByteArray = new ByteArray;
144			var md5:MD5 = new MD5;
145			seed.writeBytes(md5.hash(handshakeMessages),0,md5.getHashSize());
146			var sha:SHA1 = new SHA1;
147			seed.writeBytes(sha.hash(handshakeMessages),0,sha.getHashSize());
148			
149			// Now that I have my hashes of existing handshake messages (which I'm not sure about the length of yet) then 
150			// Sign that with my private key
151			seed.position = 0;
152			var out:ByteArray = new ByteArray();
153			key.sign( seed, out, seed.bytesAvailable);
154			out.position = 0;
155			return out;	
156		}
157		
158		public function getConnectionStates():Object {
159			if (masterSecret != null) {
160				var seed:ByteArray = new ByteArray;
161				seed.writeBytes(serverRandom, 0, serverRandom.length);
162				seed.writeBytes(clientRandom, 0, clientRandom.length);
163				var prf:TLSPRF = new TLSPRF(masterSecret, "key expansion", seed);
164				
165				var client_write_MAC:ByteArray = new ByteArray;
166				prf.nextBytes(client_write_MAC, hashSize);
167				var server_write_MAC:ByteArray = new ByteArray;
168				prf.nextBytes(server_write_MAC, hashSize);
169				var client_write_key:ByteArray = new ByteArray;
170				prf.nextBytes(client_write_key, keyMaterialLength);
171				var server_write_key:ByteArray = new ByteArray;
172				prf.nextBytes(server_write_key, keyMaterialLength);
173				var client_write_IV:ByteArray = new ByteArray;
174				prf.nextBytes(client_write_IV, IVSize);
175				var server_write_IV:ByteArray = new ByteArray;
176				prf.nextBytes(server_write_IV, IVSize);
177
178				var client_write:TLSConnectionState = new TLSConnectionState(
179						bulkCipher, cipherType, macAlgorithm,
180						client_write_MAC, client_write_key, client_write_IV);
181				var server_write:TLSConnectionState = new TLSConnectionState(
182						bulkCipher, cipherType, macAlgorithm,
183						server_write_MAC, server_write_key, server_write_IV);
184				
185				if (entity == TLSEngine.CLIENT) {
186					return {read:server_write, write:client_write};
187				} else {
188					return {read:client_write, write:server_write};
189				}
190
191			} else {
192				return {read:new TLSConnectionState, write:new TLSConnectionState};
193			}
194		}
195		
196	}
197}