PageRenderTime 103ms CodeModel.GetById 40ms app.highlight 12ms RepoModel.GetById 49ms app.codeStats 0ms

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

http://github.com/onedayitwillmake/RealtimeMultiplayerNodeJs
ActionScript | 171 lines | 114 code | 23 blank | 34 comment | 24 complexity | 02301bb3725990f16ecb8c67e1fb5693 MD5 | raw file
  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 */
 10package 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.MAC;
 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 SSLConnectionState implements IConnectionState {
 22
 23		// compression state
 24		
 25		// cipher state
 26		private var bulkCipher:uint;
 27		private var cipherType:uint;
 28		private var CIPHER_key:ByteArray;
 29		private var CIPHER_IV:ByteArray;
 30		private var cipher:ICipher;
 31		private var ivmode:IVMode;
 32		
 33		// mac secret
 34		private var macAlgorithm:uint;
 35		private var MAC_write_secret:ByteArray;
 36		private var mac:MAC;
 37		
 38		// sequence number. uint64
 39		
 40		private var seq_lo:uint = 0x0;
 41		private var seq_hi:uint = 0x0;
 42
 43		public function SSLConnectionState(
 44				bulkCipher:uint=0, cipherType:uint=0, macAlgorithm:uint=0,
 45				mac_enc:ByteArray=null, key:ByteArray=null, IV:ByteArray=null) {
 46			this.bulkCipher = bulkCipher;
 47			this.cipherType = cipherType;
 48			this.macAlgorithm = macAlgorithm;
 49			MAC_write_secret = mac_enc;
 50			mac = MACs.getMAC(macAlgorithm);
 51			
 52			CIPHER_key = key;
 53			CIPHER_IV = IV;
 54			cipher = BulkCiphers.getCipher(bulkCipher, key, 0x0300);
 55			if (cipher is IVMode) {
 56				ivmode = cipher as IVMode;
 57				ivmode.IV = IV;
 58			}
 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				p.position = 0;
 73				// block cipher
 74				if (bulkCipher == BulkCiphers.NULL) {
 75				
 76				} else {
 77					var nextIV:ByteArray = new ByteArray;
 78					nextIV.writeBytes(p, p.length-CIPHER_IV.length, CIPHER_IV.length);
 79					p.position = 0;
 80					cipher.decrypt(p);
 81
 82					CIPHER_IV = nextIV;
 83					ivmode.IV = nextIV;
 84				}
 85			}
 86	
 87			if (macAlgorithm!=MACs.NULL) {
 88				// there will be CTX delay here as well, 
 89				// I should probably optmize the hell out of it
 90				var data:ByteArray = new ByteArray;
 91				var len:uint = p.length - mac.getHashSize();
 92				data.writeUnsignedInt(seq_hi);
 93				data.writeUnsignedInt(seq_lo);
 94				
 95				data.writeByte(type);
 96				data.writeShort(len);
 97				if (len!=0) {
 98					data.writeBytes(p, 0, len);
 99				}
100				var mac_enc:ByteArray = mac.compute(MAC_write_secret, data);
101				// compare "mac" with the last X bytes of p.
102				var mac_received:ByteArray = new ByteArray;
103				mac_received.writeBytes(p, len, mac.getHashSize());
104				if (ArrayUtil.equals(mac_enc, mac_received)) {
105					// happy happy joy joy
106				} else {
107					throw new TLSError("Bad Mac Data", TLSError.bad_record_mac);
108				}
109				p.length = len;
110				p.position = 0;
111			}
112			// increment seq
113			seq_lo++;
114			if (seq_lo==0) seq_hi++;
115			return p;
116		}
117		public function encrypt(type:uint, p:ByteArray):ByteArray {
118			var mac_enc:ByteArray = null;
119			if (macAlgorithm!=MACs.NULL) {
120				var data:ByteArray = new ByteArray;
121				// data.writeUnsignedInt(seq);
122				
123				// Sequence
124				data.writeUnsignedInt(seq_hi);
125				data.writeUnsignedInt(seq_lo);
126				
127				// Type
128				data.writeByte(type);
129				
130				// Length
131				data.writeShort(p.length);
132				
133				// The data
134				if (p.length!=0) {
135					data.writeBytes(p);
136				}
137			
138				// trace("data for the MAC: " + Hex.fromArray(data));
139				mac_enc = mac.compute(MAC_write_secret, data);
140				// trace("MAC: " + Hex.fromArray( mac_enc ));
141				p.position = p.length;
142				p.writeBytes(mac_enc);
143			}
144			
145			// trace("Record to encrypt: " + Hex.fromArray(p));
146			
147			p.position = 0;
148			if (cipherType == BulkCiphers.STREAM_CIPHER) {
149				// stream cipher
150				if (bulkCipher == BulkCiphers.NULL) {
151					// no-op
152				} else {
153					cipher.encrypt(p);
154				}
155			} else {
156				// block cipher
157				cipher.encrypt(p);
158				// adjust IV
159				var nextIV:ByteArray = new ByteArray;
160				nextIV.writeBytes(p, p.length-CIPHER_IV.length, CIPHER_IV.length);
161				CIPHER_IV = nextIV;
162				ivmode.IV = nextIV;
163			}
164			// increment seq
165			seq_lo++;
166			if (seq_lo==0) seq_hi++;
167			return p;
168		}
169		
170	}
171}