tweetcast/client/lib/websocket-js/flash-src/third-party/com/hurlant/crypto/Crypto.as
changeset 306 70c9688a1486
parent 305 436a31d11f1d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tweetcast/client/lib/websocket-js/flash-src/third-party/com/hurlant/crypto/Crypto.as	Thu Oct 06 12:39:29 2011 +0200
@@ -0,0 +1,287 @@
+/**
+ * Crypto
+ * 
+ * An abstraction layer to instanciate our crypto algorithms
+ * Copyright (c) 2007 Henri Torgemane
+ * 
+ * See LICENSE.txt for full license information.
+ */
+package com.hurlant.crypto
+{
+	import com.hurlant.crypto.hash.HMAC;
+	import com.hurlant.crypto.hash.MAC;
+	import com.hurlant.crypto.hash.IHash;
+	import com.hurlant.crypto.hash.MD2;
+	import com.hurlant.crypto.hash.MD5;
+	import com.hurlant.crypto.hash.SHA1;
+	import com.hurlant.crypto.hash.SHA224;
+	import com.hurlant.crypto.hash.SHA256;
+	import com.hurlant.crypto.prng.ARC4;
+	import com.hurlant.crypto.rsa.RSAKey;
+	import com.hurlant.crypto.symmetric.AESKey;
+	import com.hurlant.crypto.symmetric.BlowFishKey;
+	import com.hurlant.crypto.symmetric.CBCMode;
+	import com.hurlant.crypto.symmetric.CFB8Mode;
+	import com.hurlant.crypto.symmetric.CFBMode;
+	import com.hurlant.crypto.symmetric.CTRMode;
+	import com.hurlant.crypto.symmetric.DESKey;
+	import com.hurlant.crypto.symmetric.ECBMode;
+	import com.hurlant.crypto.symmetric.ICipher;
+	import com.hurlant.crypto.symmetric.IMode;
+	import com.hurlant.crypto.symmetric.IPad;
+	import com.hurlant.crypto.symmetric.ISymmetricKey;
+	import com.hurlant.crypto.symmetric.IVMode;
+	import com.hurlant.crypto.symmetric.NullPad;
+	import com.hurlant.crypto.symmetric.OFBMode;
+	import com.hurlant.crypto.symmetric.PKCS5;
+	import com.hurlant.crypto.symmetric.SimpleIVMode;
+	import com.hurlant.crypto.symmetric.TripleDESKey;
+	import com.hurlant.crypto.symmetric.XTeaKey;
+	import com.hurlant.util.Base64;
+	
+	import flash.utils.ByteArray;
+	
+	/**
+	 * A class to make it easy to use the rest of the framework.
+	 * As a side-effect, using this class will cause most of the framework
+	 * to be linked into your application, which is not always what you want.
+	 * 
+	 * If you want to optimize your download size, don't use this class.
+	 * (But feel free to read it to get ideas on how to get the algorithm you want.)
+	 */
+	public class Crypto
+	{
+		private var b64:Base64; // we don't use it, but we want the swc to include it, so cheap trick.
+		
+		public function Crypto(){
+		}
+		
+		/**
+		 * Things that should work, among others:
+		 *  "aes"
+		 *  "aes-128-ecb"
+		 *  "aes-128-cbc"
+		 *  "aes-128-cfb"
+		 *  "aes-128-cfb8"
+		 *  "aes-128-ofb"
+		 *  "aes-192-cfb"
+		 *  "aes-256-ofb"
+		 *  "blowfish-cbc"
+		 *  "des-ecb"
+		 *  "xtea"
+		 *  "xtea-ecb"
+		 *  "xtea-cbc"
+		 *  "xtea-cfb"
+		 *  "xtea-cfb8"
+		 *  "xtea-ofb"
+		 *  "rc4"
+		 *  "simple-aes-cbc"
+		 */
+		public static function getCipher(name:String, key:ByteArray, pad:IPad=null):ICipher {
+			// split name into an array.
+			var keys:Array = name.split("-");
+			switch (keys[0]) {
+				/**
+				 * "simple" is a special case. It means:
+				 * "If using an IV mode, prepend the IV to the ciphertext"
+				 */
+				case "simple":
+					keys.shift();
+					name = keys.join("-");
+					var cipher:ICipher = getCipher(name, key, pad);
+					if (cipher is IVMode) {
+						return new SimpleIVMode(cipher as IVMode);
+					} else {
+						return cipher;
+					}
+				/**
+				 * we support both "aes-128" and "aes128"
+				 * Technically, you could use "aes192-128", but you'd
+				 * only be hurting yourself.
+				 */
+				case "aes":
+				case "aes128":
+				case "aes192":
+				case "aes256":
+					keys.shift();
+					if (key.length*8==keys[0]) {
+						// support for "aes-128-..." and such.
+						keys.shift();
+					}
+					return getMode(keys[0], new AESKey(key), pad);
+				break;
+				case "bf":
+				case "blowfish":
+					keys.shift();
+					return getMode(keys[0], new BlowFishKey(key), pad);
+				/**
+				 * des-ede and des-ede3 are both equivalent to des3.
+				 * the choice between 2tdes and 3tdes is made based
+				 * on the length of the key provided.
+				 */
+				case "des":
+					keys.shift();
+					if (keys[0]!="ede" && keys[0]!="ede3") {
+						return getMode(keys[0], new DESKey(key), pad);
+					}
+					if (keys.length==1) {
+						keys.push("ecb"); // default mode for 2tdes and 3tdes with openssl enc
+					}
+					// fall-through to triple des
+				case "3des":
+				case "des3":
+					keys.shift();
+					return getMode(keys[0], new TripleDESKey(key), pad);
+				case "xtea":
+					keys.shift();
+					return getMode(keys[0], new XTeaKey(key), pad);
+				break;
+				/**
+				 * Technically, you could say "rc4-128" or whatever,
+				 * but really, the length of the key is what counts here.
+				 */
+				case "rc4":
+					keys.shift();
+					return new ARC4(key);
+				break;
+			}
+			return null;
+		}
+		
+		/**
+		 * Returns the size of a key for a given cipher identifier.
+		 */
+		public static function getKeySize(name:String):uint {
+			var keys:Array = name.split("-");
+			switch (keys[0]) {
+				case "simple":
+					keys.shift();
+					return getKeySize(keys.join("-"));
+				case "aes128":
+					return 16;
+				case "aes192":
+					return 24;
+				case "aes256":
+					return 32;
+				case "aes":
+					keys.shift();
+					return parseInt(keys[0])/8;
+				case "bf":
+				case "blowfish":
+					return 16;
+				case "des":
+					keys.shift();
+					switch (keys[0]) {
+						case "ede":
+							return 16;
+						case "ede3":
+							return 24;
+						default:
+							return 8;
+					}
+				case "3des":
+				case "des3":
+					return 24;
+				case "xtea":
+					return 8;
+				case "rc4":
+					if (parseInt(keys[1])>0) {
+						return parseInt(keys[1])/8;
+					}
+					return 16; // why not.
+			}
+			return 0; // unknown;
+		}
+		
+		private static function getMode(name:String, alg:ISymmetricKey, padding:IPad=null):IMode {
+			switch (name) {
+				case "ecb":
+					return new ECBMode(alg, padding);
+				case "cfb":
+					return new CFBMode(alg, padding);
+				case "cfb8":
+					return new CFB8Mode(alg, padding);
+				case "ofb":
+					return new OFBMode(alg, padding);
+				case "ctr":
+					return new CTRMode(alg, padding);
+				case "cbc":
+				default:
+					return new CBCMode(alg, padding);
+			}
+		}
+		
+		/**
+		 * Things that should work:
+		 * "md5"
+		 * "sha"
+		 * "sha1"
+		 * "sha224"
+		 * "sha256"
+		 */
+		public static function getHash(name:String):IHash {
+			switch(name) {
+				case "md2":
+					return new MD2;
+				case "md5":
+					return new MD5;
+				case "sha": // let's hope you didn't mean sha-0
+				case "sha1":
+					return new SHA1;
+				case "sha224":
+					return new SHA224;
+				case "sha256":
+					return new SHA256;
+			}
+			return null;
+		}
+		
+		/**
+		 * Things that should work:
+		 * "sha1"
+		 * "md5-64"
+		 * "hmac-md5-96"
+		 * "hmac-sha1-128"
+		 * "hmac-sha256-192"
+		 * etc.
+		 */
+		public static function getHMAC(name:String):HMAC {
+			var keys:Array = name.split("-");
+			if (keys[0]=="hmac") keys.shift();
+			var bits:uint = 0;
+			if (keys.length>1) {
+				bits = parseInt(keys[1]);
+			}
+			return new HMAC(getHash(keys[0]), bits);
+		}
+		
+
+		public static function getMAC(name:String):MAC {
+			
+			var keys:Array = name.split("-");
+			if (keys[0]=="mac") keys.shift();
+			var bits:uint = 0;
+			if (keys.length > 1) {
+				bits = parseInt(keys[1]);
+			}
+			return new MAC(getHash(keys[0]), bits);
+		}
+				
+		
+		public static function getPad(name:String):IPad {
+			switch(name) {
+				case "null":
+					return new NullPad;
+				case "pkcs5":
+				default:
+					return new PKCS5;
+			}
+		}
+		
+		/** mostly useless.
+		 */
+		public static function getRSA(E:String, M:String):RSAKey {
+			return RSAKey.parsePublicKey(M,E);
+		}
+	}
+}
\ No newline at end of file