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

http://github.com/onedayitwillmake/RealtimeMultiplayerNodeJs · ActionScript · 197 lines · 154 code · 24 blank · 19 comment · 10 complexity · ab63d4a22710cb8f8a1e2eb7931f1aa3 MD5 · raw file

  1. /**
  2. * TLSSecurityParameters
  3. *
  4. * This class encapsulates all the security parameters that get negotiated
  5. * during the TLS handshake. It also holds all the key derivation methods.
  6. * Copyright (c) 2007 Henri Torgemane
  7. *
  8. * Patched by Bobby Parker (sh0rtwave@gmail.com)
  9. *
  10. * See LICENSE.txt for full license information.
  11. */
  12. package com.hurlant.crypto.tls {
  13. import com.hurlant.crypto.hash.MD5;
  14. import com.hurlant.crypto.hash.SHA1;
  15. import com.hurlant.crypto.prng.TLSPRF;
  16. import com.hurlant.util.Hex;
  17. import flash.utils.ByteArray;
  18. import com.hurlant.crypto.rsa.RSAKey;
  19. public class TLSSecurityParameters implements ISecurityParameters {
  20. // COMPRESSION
  21. public static const COMPRESSION_NULL:uint = 0;
  22. // This is probably not smart. Revise this to use all settings from TLSConfig, since this shouldn't really know about
  23. // user settings, those are best handled from the engine at a session level.
  24. public static var IGNORE_CN_MISMATCH:Boolean = true;
  25. public static var ENABLE_USER_CLIENT_CERTIFICATE:Boolean = false;
  26. public static var USER_CERTIFICATE:String;
  27. private var cert:ByteArray; // Local Cert
  28. private var key:RSAKey; // local key
  29. private var entity:uint; // SERVER | CLIENT
  30. private var bulkCipher:uint; // BULK_CIPHER_*
  31. private var cipherType:uint; // STREAM_CIPHER | BLOCK_CIPHER
  32. private var keySize:uint;
  33. private var keyMaterialLength:uint;
  34. private var IVSize:uint;
  35. private var macAlgorithm:uint; // MAC_*
  36. private var hashSize:uint;
  37. private var compression:uint; // COMPRESSION_NULL
  38. private var masterSecret:ByteArray; // 48 bytes
  39. private var clientRandom:ByteArray; // 32 bytes
  40. private var serverRandom:ByteArray; // 32 bytes
  41. private var ignoreCNMismatch:Boolean = true;
  42. private var trustAllCerts:Boolean = false;
  43. private var trustSelfSigned:Boolean = false;
  44. public static const PROTOCOL_VERSION:uint = 0x0301;
  45. private var tlsDebug:Boolean = false;
  46. // not strictly speaking part of this, but yeah.
  47. public var keyExchange:uint;
  48. public function TLSSecurityParameters(entity:uint, localCert:ByteArray = null, localKey:RSAKey = null) {
  49. this.entity = entity;
  50. reset();
  51. key = localKey;
  52. cert = localCert;
  53. }
  54. public function get version() : uint {
  55. return PROTOCOL_VERSION;
  56. }
  57. public function reset():void {
  58. bulkCipher = BulkCiphers.NULL;
  59. cipherType = BulkCiphers.BLOCK_CIPHER;
  60. macAlgorithm = MACs.NULL;
  61. compression = COMPRESSION_NULL;
  62. masterSecret = null;
  63. }
  64. public function getBulkCipher():uint {
  65. return bulkCipher;
  66. }
  67. public function getCipherType():uint {
  68. return cipherType;
  69. }
  70. public function getMacAlgorithm():uint {
  71. return macAlgorithm;
  72. }
  73. public function setCipher(cipher:uint):void {
  74. bulkCipher = CipherSuites.getBulkCipher(cipher);
  75. cipherType = BulkCiphers.getType(bulkCipher);
  76. keySize = BulkCiphers.getExpandedKeyBytes(bulkCipher); // 8
  77. keyMaterialLength = BulkCiphers.getKeyBytes(bulkCipher); // 5
  78. IVSize = BulkCiphers.getIVSize(bulkCipher);
  79. keyExchange = CipherSuites.getKeyExchange(cipher);
  80. macAlgorithm = CipherSuites.getMac(cipher);
  81. hashSize = MACs.getHashSize(macAlgorithm);
  82. }
  83. public function setCompression(algo:uint):void {
  84. compression = algo;
  85. }
  86. public function setPreMasterSecret(secret:ByteArray):void {
  87. // compute master_secret
  88. var seed:ByteArray = new ByteArray;
  89. seed.writeBytes(clientRandom, 0, clientRandom.length);
  90. seed.writeBytes(serverRandom, 0, serverRandom.length);
  91. var prf:TLSPRF = new TLSPRF(secret, "master secret", seed);
  92. masterSecret = new ByteArray;
  93. prf.nextBytes(masterSecret, 48);
  94. if (tlsDebug)
  95. trace("Master Secret: " + Hex.fromArray( masterSecret, true ));
  96. }
  97. public function setClientRandom(secret:ByteArray):void {
  98. clientRandom = secret;
  99. }
  100. public function setServerRandom(secret:ByteArray):void {
  101. serverRandom = secret;
  102. }
  103. public function get useRSA():Boolean {
  104. return KeyExchanges.useRSA(keyExchange);
  105. }
  106. public function computeVerifyData(side:uint, handshakeMessages:ByteArray):ByteArray {
  107. var seed:ByteArray = new ByteArray;
  108. var md5:MD5 = new MD5;
  109. if (tlsDebug)
  110. trace("Handshake value: " + Hex.fromArray(handshakeMessages, true ));
  111. seed.writeBytes(md5.hash(handshakeMessages),0,md5.getHashSize());
  112. var sha:SHA1 = new SHA1;
  113. seed.writeBytes(sha.hash(handshakeMessages),0,sha.getHashSize());
  114. if (tlsDebug)
  115. trace("Seed in: " + Hex.fromArray(seed, true ));
  116. var prf:TLSPRF = new TLSPRF(masterSecret, (side==TLSEngine.CLIENT) ? "client finished" : "server finished", seed);
  117. var out:ByteArray = new ByteArray;
  118. prf.nextBytes(out, 12);
  119. if (tlsDebug)
  120. trace("Finished out: " + Hex.fromArray(out, true ));
  121. out.position = 0;
  122. return out;
  123. }
  124. // client side certficate check - This is probably incorrect somehow
  125. public function computeCertificateVerify( side:uint, handshakeMessages:ByteArray ):ByteArray {
  126. var seed:ByteArray = new ByteArray;
  127. var md5:MD5 = new MD5;
  128. seed.writeBytes(md5.hash(handshakeMessages),0,md5.getHashSize());
  129. var sha:SHA1 = new SHA1;
  130. seed.writeBytes(sha.hash(handshakeMessages),0,sha.getHashSize());
  131. // Now that I have my hashes of existing handshake messages (which I'm not sure about the length of yet) then
  132. // Sign that with my private key
  133. seed.position = 0;
  134. var out:ByteArray = new ByteArray();
  135. key.sign( seed, out, seed.bytesAvailable);
  136. out.position = 0;
  137. return out;
  138. }
  139. public function getConnectionStates():Object {
  140. if (masterSecret != null) {
  141. var seed:ByteArray = new ByteArray;
  142. seed.writeBytes(serverRandom, 0, serverRandom.length);
  143. seed.writeBytes(clientRandom, 0, clientRandom.length);
  144. var prf:TLSPRF = new TLSPRF(masterSecret, "key expansion", seed);
  145. var client_write_MAC:ByteArray = new ByteArray;
  146. prf.nextBytes(client_write_MAC, hashSize);
  147. var server_write_MAC:ByteArray = new ByteArray;
  148. prf.nextBytes(server_write_MAC, hashSize);
  149. var client_write_key:ByteArray = new ByteArray;
  150. prf.nextBytes(client_write_key, keyMaterialLength);
  151. var server_write_key:ByteArray = new ByteArray;
  152. prf.nextBytes(server_write_key, keyMaterialLength);
  153. var client_write_IV:ByteArray = new ByteArray;
  154. prf.nextBytes(client_write_IV, IVSize);
  155. var server_write_IV:ByteArray = new ByteArray;
  156. prf.nextBytes(server_write_IV, IVSize);
  157. var client_write:TLSConnectionState = new TLSConnectionState(
  158. bulkCipher, cipherType, macAlgorithm,
  159. client_write_MAC, client_write_key, client_write_IV);
  160. var server_write:TLSConnectionState = new TLSConnectionState(
  161. bulkCipher, cipherType, macAlgorithm,
  162. server_write_MAC, server_write_key, server_write_IV);
  163. if (entity == TLSEngine.CLIENT) {
  164. return {read:server_write, write:client_write};
  165. } else {
  166. return {read:client_write, write:server_write};
  167. }
  168. } else {
  169. return {read:new TLSConnectionState, write:new TLSConnectionState};
  170. }
  171. }
  172. }
  173. }