예제 #1
0
        public static void ServerHelloDone(TlsConnection connection)
        {
            Log.Info("Send ServerHelloDone");

            byte[] data = new byte[0];
            TlsResponse.Handshake(connection, 14, ref data);
        }
예제 #2
0
        public static void ServerKeyExchange(TlsConnection connection)
        {
            Log.Info("Send ServerKeyExchange");

            byte[] data = new byte[7 +
                                   TlsConnection.SrpNBytes.Length +
                                   TlsConnection.SrpGBytes.Length +
                                   TlsConnection.SrpSBytes.Length +
                                   connection.SrpB.Length];

            //N
            data[0] = (byte)(TlsConnection.SrpNBytes.Length >> 8);
            data[1] = (byte)TlsConnection.SrpNBytes.Length;
            Buffer.BlockCopy(TlsConnection.SrpNBytes, 0, data, 2, TlsConnection.SrpNBytes.Length);
            int offset = TlsConnection.SrpNBytes.Length + 2;

            //G
            data[offset]     = (byte)(TlsConnection.SrpGBytes.Length >> 8);
            data[offset + 1] = (byte)TlsConnection.SrpGBytes.Length;
            Buffer.BlockCopy(TlsConnection.SrpGBytes, 0, data, offset + 2, TlsConnection.SrpGBytes.Length);
            offset += TlsConnection.SrpGBytes.Length + 2;

            //S
            data[offset] = (byte)TlsConnection.SrpSBytes.Length;
            Buffer.BlockCopy(TlsConnection.SrpSBytes, 0, data, offset + 1, TlsConnection.SrpSBytes.Length);
            offset += TlsConnection.SrpSBytes.Length + 1;

            //B
            data[offset]     = (byte)(connection.SrpB.Length >> 8);
            data[offset + 1] = (byte)connection.SrpB.Length;
            Buffer.BlockCopy(connection.SrpB, 0, data, offset + 2, connection.SrpB.Length);

            TlsResponse.Handshake(connection, 12, ref data);
        }
예제 #3
0
        public static void ServerChangeCipherSpec(TlsConnection connection)
        {
            Log.Info("Send ServerChangeCipherSpec");

            byte[] data = new byte[] { 1 };
            TlsResponse.ChangeCipherSpec(connection, ref data);
        }
예제 #4
0
        public static void ClientFinish(TlsConnection connection, int length)
        {
            Log.Info("Recv ClientFinish");

            var sha256        = SHA256.Create();
            var handshakeData = connection.HandshakeMessages.GetRange(0, connection.HandshakeMessages.Count - length - 4).ToArray();
            var handshakeHash = sha256.ComputeHash(handshakeData);

            var prfClient = new PseudoRandomFunction(connection.MasterSecretBytes, "client finished", handshakeHash);

            byte[] clientVerifyData = prfClient.GenerateBytes(12);

            byte[] data = connection.Buffer.Read(12);
            for (uint i = 0; i < 12; i++)
            {
                if (clientVerifyData[i] != data[i])
                {
                    Log.Error("Invalid ClientFinish!");
                    return;
                }
            }

            HandshakeResponse.ServerChangeCipherSpec(connection);
            connection.SendEncrypted = true;
            HandshakeResponse.ServerServerFinish(connection);
        }
예제 #5
0
        protected override TransportMessage NewTransport(string uri, Resources resources)
        {
            URL u = new URL(uri);

            Object socket = resources.Get(SOCKET);

            TransportData c;

            if (isSecure)
            {
                c = new TlsConnection((Socket)socket, u, resources);
            }
            else
            {
                c = new TcpConnection((Socket)socket, u, resources);
            }

            TransportPacket p = new Packetizer(c, u, resources);

            TransportMessage m = new Messagizer(p, u, resources);

            m = AddFilters(m, u, resources);

            //MailboxManager r = new PlainMailboxManager(m, u, resources);

            //DeliveryService d = new DefaultDeliveryService(r, u, resources);

            ValueFactory vf = (ValueFactory)resources.Get(TransportConsts.VALUE_FACTORY);

            vf.LockDynamicTypes();

            return(m);
        }
예제 #6
0
        public static void ClientKeyExchange(TlsConnection connection, int length)
        {
            Log.Info("Recv ClientKeyExchange");

            connection.PreMasterSecret =
                connection.SrpServer.CalculateSecret(
                    new BigInteger(1, connection.Buffer.Read(connection.Buffer.ReadShort())));
        }
예제 #7
0
        public void StartTls(Connection connection)
        {
            TlsConnection tlsConnection = connection as TlsConnection;

            if (tlsConnection == null)
            {
                return;
            }

            tlsConnection.StartTls();
        }
예제 #8
0
        public void PostStsMessage(Connection connection, string header, string body)
        {
            TlsConnection tlsConnection = connection as TlsConnection;

            if (tlsConnection == null)
            {
                return;
            }

            StsResponse.Post(tlsConnection, header, body);
        }
예제 #9
0
        public void SendStsMessage(Connection connection, StsMessage message)
        {
            TlsConnection tlsConnection = connection as TlsConnection;

            if (tlsConnection == null)
            {
                return;
            }

            StsResponse.SendStsMessage(tlsConnection, message);
        }
예제 #10
0
        public static void ServerServerFinish(TlsConnection connection)
        {
            Log.Info("Send ServerServerFinish");

            var sha256        = SHA256.Create();
            var handshakeHash = sha256.ComputeHash(connection.HandshakeMessages.ToArray());
            var prfClient     = new PseudoRandomFunction(connection.MasterSecretBytes, "server finished", handshakeHash);

            byte[] servVerData = prfClient.GenerateBytes(12);

            TlsResponse.Handshake(connection, 20, ref servVerData);
        }
예제 #11
0
        public static void Handshake(TlsConnection connection, byte type, ref byte[] data)
        {
            byte[] resultData = new byte[data.Length + 4];
            resultData[0] = type;
            resultData[1] = (byte)(data.Length >> 16);
            resultData[2] = (byte)(data.Length >> 8);
            resultData[3] = (byte)data.Length;
            Buffer.BlockCopy(data, 0, resultData, 4, data.Length);

            if (connection.HandshakeMessages != null)
            {
                connection.HandshakeMessages.AddRange(resultData);
            }

            Send(connection, 22, ref resultData);
        }
예제 #12
0
        public static void Post(TlsConnection connection, string request, string body)
        {
            StringBuilder builder = new StringBuilder("P ", request.Length + body.Length + 24);

            builder.Append(request);
            builder.Append(" STS/1.0\r\nl:");
            builder.Append(body.Length);
            builder.Append("\r\n\r\n");
            builder.Append(body);

            byte[] data = Encoding.ASCII.GetBytes(builder.ToString());

            if (connection.SendEncrypted)
            {
                TlsResponse.Message(connection, ref data);
            }
        }
예제 #13
0
        private static void Send(TlsConnection connection, byte type, ref byte[] data)
        {
            if (connection.SendEncrypted)
            {
                data = Encrypt(connection, type, ref data);
            }

            byte[] resultData = new byte[data.Length + 5];
            resultData[0] = type;
            resultData[1] = 3;
            resultData[2] = 3;
            resultData[3] = (byte)(data.Length >> 8);
            resultData[4] = (byte)data.Length;
            Buffer.BlockCopy(data, 0, resultData, 5, data.Length);

            connection.Send(resultData);
        }
예제 #14
0
        public static void ClientHello(TlsConnection connection, int length)
        {
            connection.Buffer.ReadIndex += 2;
            connection.ClientRandom      = connection.Buffer.Read(32);
            connection.Buffer.ReadIndex++;
            int cipherSuitesLength = connection.Buffer.ReadShort();

            connection.Buffer.ReadIndex += cipherSuitesLength;
            connection.Buffer.ReadIndex += 2;

            string login = "";

            int extensionsLength = connection.Buffer.ReadShort();

            while (extensionsLength > 0)
            {
                int    extensionId   = connection.Buffer.ReadShort();
                byte[] extensionData = connection.Buffer.Read(connection.Buffer.ReadShort());

                if (extensionId == 12)
                {
                    login = Encoding.ASCII.GetString(extensionData, 1, extensionData[0]);
                    break;
                }
            }

            Log.InfoFormat("Recv ClientHello: {0}", login);

            var ac = GtSGlobal.AuthEngine.ClientAuth(connection, login, "1");

            if (ac != null)
            {
                connection.Account = ac;

                connection.InitSrp(login);

                HandshakeResponse.ServerHello(connection);
                HandshakeResponse.ServerKeyExchange(connection);
                HandshakeResponse.ServerHelloDone(connection);
            }
        }
예제 #15
0
        public static void ServerHello(TlsConnection connection)
        {
            Log.Info("Send ServerHello");

            byte[] data = new byte[]
            {
                0x03, 0x03     // Version: TLS 1.2
                , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
                , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
                , 0x00       // Session ID length: 0
                , 0xc0, 0x1d // Cipher suite: TLS_SRP_SHA_WITH_AES_128_CBC_SHA
                , 0x00       // Compression method: null
            };

            connection.ServerRandom = new byte[32];
            Utils.Random.NextBytes(connection.ServerRandom);

            Buffer.BlockCopy(connection.ServerRandom, 0, data, 2, 32);

            TlsResponse.Handshake(connection, 2, ref data);
        }
예제 #16
0
        private static byte[] Encrypt(TlsConnection connection, byte type, ref byte[] data)
        {
            byte[] toHash = new byte[13 + data.Length];

            toHash[0] = (byte)(connection.TlsSequence >> 56);
            toHash[1] = (byte)(connection.TlsSequence >> 48);
            toHash[2] = (byte)(connection.TlsSequence >> 40);
            toHash[3] = (byte)(connection.TlsSequence >> 32);
            toHash[4] = (byte)(connection.TlsSequence >> 24);
            toHash[5] = (byte)(connection.TlsSequence >> 16);
            toHash[6] = (byte)(connection.TlsSequence >> 8);
            toHash[7] = (byte)connection.TlsSequence;

            connection.TlsSequence++;

            toHash[8]  = type;
            toHash[9]  = 3;
            toHash[10] = 3;
            toHash[11] = (byte)(data.Length >> 8);
            toHash[12] = (byte)data.Length;

            Buffer.BlockCopy(data, 0, toHash, 13, data.Length);

            var mac = new HMACSHA1(connection.ServerWriteMacKey);

            byte[] hash = mac.ComputeHash(toHash, 0, toHash.Length);

            var aes = new AesManaged();

            aes.GenerateIV();
            aes.Key     = connection.ServerWriteKey;
            aes.Padding = PaddingMode.PKCS7;

            byte padding = (byte)(((((data.Length + 20) >> 4) + 1) << 4) - data.Length - 21);

            byte[] toCipher  = data.Concat(hash).Concat(new[] { padding }).ToArray();
            byte[] encrypted = aes.CreateEncryptor().TransformFinalBlock(toCipher, 0, toCipher.Length);

            return(aes.IV.Concat(encrypted).ToArray());
        }
예제 #17
0
        private static void Send(TlsConnection connection, string header, string response)
        {
            StringBuilder builder = new StringBuilder(header, header.Length + response.Length + 24);

            builder.Append("\r\nl:");
            builder.Append(response.Length);
            builder.Append("\r\ns:");
            builder.Append(connection.StsSequence);
            builder.Append("R\r\n\r\n");
            builder.Append(response);

            byte[] data = Encoding.ASCII.GetBytes(builder.ToString());

            if (connection.SendEncrypted)
            {
                TlsResponse.Message(connection, ref data);
            }
            else
            {
                connection.Send(data);
            }
        }
예제 #18
0
 public static void ChangeCipherSpec(TlsConnection connection, ref byte[] data)
 {
     Send(connection, 20, ref data);
 }
예제 #19
0
 public static void Ok(TlsConnection connection, string response)
 {
     Send(connection, "STS/1.0 200 OK", response);
 }
예제 #20
0
 public static void Success(TlsConnection connection, string response)
 {
     Send(connection, "STS/1.0 400 Success", response);
 }
예제 #21
0
 public static void SendStsMessage(TlsConnection connection, StsMessage stsMessage)
 {
     Send(connection, stsMessage.MessageHeader, stsMessage.ToString());
 }
예제 #22
0
 public static void SendStsMessage(TlsConnection connection, string header, string body)
 {
     Send(connection, header, body);
 }
예제 #23
0
 public static void Message(TlsConnection connection, ref byte[] data)
 {
     Send(connection, 23, ref data);
 }