PageRenderTime 133ms CodeModel.GetById 101ms app.highlight 11ms RepoModel.GetById 19ms app.codeStats 0ms

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

http://github.com/onedayitwillmake/RealtimeMultiplayerNodeJs
ActionScript | 151 lines | 111 code | 15 blank | 25 comment | 21 complexity | fb6374e292af96fc7348847809405b94 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.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}