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
8
* See LICENSE.txt for full license information.
10
package 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;
21
public class SSLConnectionState implements IConnectionState {
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;
34
private var macAlgorithm:uint;
35
private var MAC_write_secret:ByteArray;
38
// sequence number. uint64
40
private var seq_lo:uint = 0x0;
41
private var seq_hi:uint = 0x0;
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);
54
cipher = BulkCiphers.getCipher(bulkCipher, key, 0x0300);
55
if (cipher is IVMode) {
56
ivmode = cipher as IVMode;
62
public function decrypt(type:uint, length:uint, p:ByteArray):ByteArray {
63
// decompression is a nop.
65
if (cipherType == BulkCiphers.STREAM_CIPHER) {
66
if (bulkCipher == BulkCiphers.NULL) {
74
if (bulkCipher == BulkCiphers.NULL) {
77
var nextIV:ByteArray = new ByteArray;
78
nextIV.writeBytes(p, p.length-CIPHER_IV.length, CIPHER_IV.length);
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);
98
data.writeBytes(p, 0, len);
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
107
throw new TLSError("Bad Mac Data", TLSError.bad_record_mac);
114
if (seq_lo==0) seq_hi++;
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);
124
data.writeUnsignedInt(seq_hi);
125
data.writeUnsignedInt(seq_lo);
128
data.writeByte(type);
131
data.writeShort(p.length);
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);
145
// trace("Record to encrypt: " + Hex.fromArray(p));
148
if (cipherType == BulkCiphers.STREAM_CIPHER) {
150
if (bulkCipher == BulkCiphers.NULL) {
159
var nextIV:ByteArray = new ByteArray;
160
nextIV.writeBytes(p, p.length-CIPHER_IV.length, CIPHER_IV.length);
166
if (seq_lo==0) seq_hi++;
b'\\ No newline at end of file'