/flash-src/third-party/com/hurlant/crypto/prng/TLSPRF.as
http://github.com/gimite/web-socket-js · ActionScript · 142 lines · 107 code · 10 blank · 25 comment · 4 complexity · 3cfc54c6c87288574d5d2c545d45435a MD5 · raw file
- /**
- * TLSPRF
- *
- * An ActionScript 3 implementation of a pseudo-random generator
- * that follows the TLS specification
- * Copyright (c) 2007 Henri Torgemane
- *
- * See LICENSE.txt for full license information.
- */
- package com.hurlant.crypto.prng
- {
- import flash.utils.ByteArray;
- import com.hurlant.crypto.hash.HMAC;
- import com.hurlant.crypto.hash.MD5;
- import com.hurlant.crypto.hash.SHA1;
- import com.hurlant.util.Memory;
- import com.hurlant.util.Hex;
- import flash.utils.IDataOutput;
-
- /**
- * There's "Random", and then there's TLS Random.
- * .
- * Still Pseudo-random, though.
- */
- public class TLSPRF
- {
- // XXX WAY TOO MANY STRUCTURES HERE
-
- // seed
- private var seed:ByteArray;
- // P_MD5's secret
- private var s1:ByteArray;
- // P_SHA-1's secret
- private var s2:ByteArray;
- // HMAC_MD5's A
- private var a1:ByteArray;
- // HMAC_SHA1's A
- private var a2:ByteArray;
- // Pool for P_MD5
- private var p1:ByteArray;
- // Pool for P_SHA1
- private var p2:ByteArray;
- // Data for HMAC_MD5
- private var d1:ByteArray;
- // Data for HMAC_SHA1
- private var d2:ByteArray;
-
-
- private var hmac_md5:HMAC;
- private var hmac_sha1:HMAC;
-
- public function TLSPRF(secret:ByteArray, label:String, seed:ByteArray) {
- var l:int = Math.ceil(secret.length/2);
- var s1:ByteArray = new ByteArray;
- var s2:ByteArray = new ByteArray;
- s1.writeBytes(secret, 0, l);
- s2.writeBytes(secret, secret.length-l, l);
- var s:ByteArray = new ByteArray;
- s.writeUTFBytes(label);
- s.writeBytes(seed);
- this.seed = s;
- this.s1 = s1;
- this.s2 = s2;
- hmac_md5 = new HMAC(new MD5);
- hmac_sha1 = new HMAC(new SHA1);
-
- this.a1 = hmac_md5.compute(s1, this.seed);
- this.a2 = hmac_sha1.compute(s2, this.seed);
-
- p1 = new ByteArray;
- p2 = new ByteArray;
-
- d1 = new ByteArray;
- d2 = new ByteArray;
- d1.position = MD5.HASH_SIZE;
- d1.writeBytes(this.seed);
- d2.position = SHA1.HASH_SIZE;
- d2.writeBytes(this.seed);
- }
-
- // XXX HORRIBLY SLOW. REWRITE.
- public function nextBytes(buffer:IDataOutput, length:int):void {
- while (length--) {
- buffer.writeByte(nextByte());
- }
- }
- public function nextByte():int {
- if (p1.bytesAvailable==0) {
- more_md5();
- }
- if (p2.bytesAvailable==0) {
- more_sha1();
- }
- return p1.readUnsignedByte()^p2.readUnsignedByte();
- }
- public function dispose():void {
- seed = dba(seed);
- s1 = dba(s1);
- s2 = dba(s2);
- a1 = dba(a1);
- a2 = dba(a2);
- p1 = dba(p1);
- p2 = dba(p2);
- d1 = dba(d1);
- d2 = dba(d2);
- hmac_md5.dispose();
- hmac_md5 = null;
- hmac_sha1.dispose();
- hmac_sha1 = null;
- Memory.gc();
- }
- public function toString():String {
- return "tls-prf";
- }
- private function dba(ba:ByteArray):ByteArray {
- for (var i:uint=0;i<ba.length;i++) {
- ba[i]=0;
- }
- ba.length=0;
- return null;
- }
- private function more_md5():void {
- d1.position=0;
- d1.writeBytes(a1);
- var p:int = p1.position;
- var more:ByteArray = hmac_md5.compute(s1, d1);
- a1 = hmac_md5.compute(s1, a1);
- p1.writeBytes(more);
- p1.position=p;
- }
- private function more_sha1():void {
- d2.position=0;
- d2.writeBytes(a2);
- var p:int = p2.position;
- var more:ByteArray = hmac_sha1.compute(s2, d2);
- a2 = hmac_sha1.compute(s2, a2);
- p2.writeBytes(more);
- p2.position=p;
- }
-
- }
- }