/js/lib/Socket.IO-node/support/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/SSLConnectionState.as
ActionScript | 171 lines | 114 code | 23 blank | 34 comment | 24 complexity | 02301bb3725990f16ecb8c67e1fb5693 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, MPL-2.0-no-copyleft-exception, BSD-3-Clause
- /**
- * TLSConnectionState
- *
- * This class encapsulates the read or write state of a TLS connection,
- * and implementes the encrypting and hashing of packets.
- * Copyright (c) 2007 Henri Torgemane
- *
- * See LICENSE.txt for full license information.
- */
- package com.hurlant.crypto.tls {
- import flash.utils.IDataInput;
- import flash.utils.ByteArray;
- import com.hurlant.crypto.hash.MD5;
- import com.hurlant.crypto.hash.MAC;
- import com.hurlant.crypto.hash.IHash;
- import com.hurlant.crypto.symmetric.ICipher;
- import com.hurlant.crypto.symmetric.IVMode;
- import com.hurlant.util.Hex;
- import com.hurlant.util.ArrayUtil;
-
- public class SSLConnectionState implements IConnectionState {
- // compression state
-
- // cipher state
- private var bulkCipher:uint;
- private var cipherType:uint;
- private var CIPHER_key:ByteArray;
- private var CIPHER_IV:ByteArray;
- private var cipher:ICipher;
- private var ivmode:IVMode;
-
- // mac secret
- private var macAlgorithm:uint;
- private var MAC_write_secret:ByteArray;
- private var mac:MAC;
-
- // sequence number. uint64
-
- private var seq_lo:uint = 0x0;
- private var seq_hi:uint = 0x0;
- public function SSLConnectionState(
- bulkCipher:uint=0, cipherType:uint=0, macAlgorithm:uint=0,
- mac_enc:ByteArray=null, key:ByteArray=null, IV:ByteArray=null) {
- this.bulkCipher = bulkCipher;
- this.cipherType = cipherType;
- this.macAlgorithm = macAlgorithm;
- MAC_write_secret = mac_enc;
- mac = MACs.getMAC(macAlgorithm);
-
- CIPHER_key = key;
- CIPHER_IV = IV;
- cipher = BulkCiphers.getCipher(bulkCipher, key, 0x0300);
- if (cipher is IVMode) {
- ivmode = cipher as IVMode;
- ivmode.IV = IV;
- }
- }
-
- public function decrypt(type:uint, length:uint, p:ByteArray):ByteArray {
- // decompression is a nop.
-
- if (cipherType == BulkCiphers.STREAM_CIPHER) {
- if (bulkCipher == BulkCiphers.NULL) {
- // no-op
- } else {
- cipher.decrypt(p);
- }
- } else {
- p.position = 0;
- // block cipher
- if (bulkCipher == BulkCiphers.NULL) {
-
- } else {
- var nextIV:ByteArray = new ByteArray;
- nextIV.writeBytes(p, p.length-CIPHER_IV.length, CIPHER_IV.length);
- p.position = 0;
- cipher.decrypt(p);
- CIPHER_IV = nextIV;
- ivmode.IV = nextIV;
- }
- }
-
- if (macAlgorithm!=MACs.NULL) {
- // there will be CTX delay here as well,
- // I should probably optmize the hell out of it
- var data:ByteArray = new ByteArray;
- var len:uint = p.length - mac.getHashSize();
- data.writeUnsignedInt(seq_hi);
- data.writeUnsignedInt(seq_lo);
-
- data.writeByte(type);
- data.writeShort(len);
- if (len!=0) {
- data.writeBytes(p, 0, len);
- }
- var mac_enc:ByteArray = mac.compute(MAC_write_secret, data);
- // compare "mac" with the last X bytes of p.
- var mac_received:ByteArray = new ByteArray;
- mac_received.writeBytes(p, len, mac.getHashSize());
- if (ArrayUtil.equals(mac_enc, mac_received)) {
- // happy happy joy joy
- } else {
- throw new TLSError("Bad Mac Data", TLSError.bad_record_mac);
- }
- p.length = len;
- p.position = 0;
- }
- // increment seq
- seq_lo++;
- if (seq_lo==0) seq_hi++;
- return p;
- }
- public function encrypt(type:uint, p:ByteArray):ByteArray {
- var mac_enc:ByteArray = null;
- if (macAlgorithm!=MACs.NULL) {
- var data:ByteArray = new ByteArray;
- // data.writeUnsignedInt(seq);
-
- // Sequence
- data.writeUnsignedInt(seq_hi);
- data.writeUnsignedInt(seq_lo);
-
- // Type
- data.writeByte(type);
-
- // Length
- data.writeShort(p.length);
-
- // The data
- if (p.length!=0) {
- data.writeBytes(p);
- }
-
- // trace("data for the MAC: " + Hex.fromArray(data));
- mac_enc = mac.compute(MAC_write_secret, data);
- // trace("MAC: " + Hex.fromArray( mac_enc ));
- p.position = p.length;
- p.writeBytes(mac_enc);
- }
-
- // trace("Record to encrypt: " + Hex.fromArray(p));
-
- p.position = 0;
- if (cipherType == BulkCiphers.STREAM_CIPHER) {
- // stream cipher
- if (bulkCipher == BulkCiphers.NULL) {
- // no-op
- } else {
- cipher.encrypt(p);
- }
- } else {
- // block cipher
- cipher.encrypt(p);
- // adjust IV
- var nextIV:ByteArray = new ByteArray;
- nextIV.writeBytes(p, p.length-CIPHER_IV.length, CIPHER_IV.length);
- CIPHER_IV = nextIV;
- ivmode.IV = nextIV;
- }
- // increment seq
- seq_lo++;
- if (seq_lo==0) seq_hi++;
- return p;
- }
-
- }
- }