Example #1
0
 public override string ToString()
 {
     return(ClientHello.ToString() + Environment.NewLine +
            ServerHello.ToString() + Environment.NewLine +
            ClientKeyExchange.ToString() + Environment.NewLine +
            Finished.ToString());
 }
        public void Write_ResultBytesAreExpected()
        {
            //Arrange
            var expectedBytes = GetMessageHexString();
            var buffer        = new byte[TlsBuffer.MaxRecordSize];
            var random        = HandshakeRandom.Parse(GetBytesOfRandom());
            var sessionId     = SessionId.Parse(GetBytesOfSessionId());

            //Act
            var cursor = new MemoryCursor(buffer);

            using (TlsRecord.StartWriting(cursor, RecordType.Handshake, ProtocolVersion.Tls12))
                using (ServerHello.StartWriting(cursor, random, Cipher.TLS_AES_128_GCM_SHA256, sessionId))
                {
                    using (cursor.StartKeyShareWriting())
                    {
                        using (KeyShareEntry.StartWriting(cursor, NamedGroup.X25519))
                        {
                            GetBytesOfPublicKey().CopyTo(cursor);
                        }
                    }

                    using (cursor.StartSupportedVersionWriting())
                    {
                        ProtocolVersion.Tls13.WriteBytes(cursor);
                    }
                }

            //Assert
            Assert.Equal(expectedBytes, Utils.ToHexString(cursor.PeekStart().ToArray()), true);
        }
Example #3
0
        public void TestKeyExchange(ScpConfig.EncryptionMode encryptionMode)
        {
            // Client side
            var clientEph       = ECDHHelper.CreateCngKey();
            var clientEphCng    = ECDHHelper.CreateECDiffieHellmanCngSha256(clientEph);
            var clientEphPubKey = clientEphCng.PublicKey();

            // Server side
            var secretarium = new MockedSecretarium(encryptionMode);

            Assert.IsTrue(secretarium.GetServerHello(clientEphPubKey, out byte[] serverHello));
            Assert.IsTrue(ServerHello.Parse(serverHello, 18, out ServerHello serverHelloObj));

            // Client side
            Assert.IsTrue(DiffieHellmanHelper.ComputeProofOfWork(serverHelloObj.proofOfWorkDetails, out byte[] proofOfWork));
            var clientProofOfWork = ByteHelper.Combine(proofOfWork.ExtendTo(32), MockedSecretarium.GenesisPubKey);

            // Server side
            Assert.IsTrue(secretarium.GetServerIdentity(clientProofOfWork, out byte[] serverIdentity));
            Assert.IsTrue(ServerIdentity.Parse(serverIdentity, out ServerIdentity serverIdentityObj));

            // Client side
            var symmetricKey = DiffieHellmanHelper.GetSymmetricKey(
                clientEphCng, serverIdentityObj.ephDHKey, serverIdentityObj.preMasterSecret);

            // Check keys are the same both sides
            Assert.IsTrue(symmetricKey.SequenceEqual(secretarium.Session.SymmetricKey));
        }
Example #4
0
 void ProcessServerHello(ServerHello serverHello)
 {
     this.playerID = serverHello.ClientId;
     Debug.Log("Received player ID: " + playerID);
     this.gameWorld.worldRadius = GameConfig.WORLD_RADIUS_REMOTE;
     Connect();
 }
Example #5
0
        private bool VerifySignature(ECPoint publicKey, ServerHello serverHello)
        {
            var ecdsa       = new EllipticCurveDSA(this.ellipticCurve);
            var byteMessage = this.GetByteMessage(serverHello);
            var r           = serverHello.Signature.R;
            var s           = serverHello.Signature.S;
            var sig         = (r, s);

            return(ecdsa.Verify(byteMessage, sig, publicKey));
        }
Example #6
0
        async Task <ServerHello> WaitServerHello()
        {
            var receive = m_Socket.ReceiveAsync();
            var res     = await receive;

            if (!ServerHello.TryUnpack(res.Buffer, res.Buffer.Length, out var packet))
            {
                throw new Exception("fail unpack ServerHello");
            }
            return(packet);
        }
Example #7
0
        public static void ParseServerHelloRecord(BytesSegment bs, ref ServerHello ch, out int size)
        {
            var payloadLen = GetRecordPayloadLength(bs, ref ch.Version);

            size = 5 + payloadLen;
            if (bs.Len < size)
            {
                return;
            }
            bs.SubSelf(5);
            bs.Len = Math.Min(bs.Len, payloadLen);
            ParseServerHello(bs, ref ch);
        }
Example #8
0
        public static bool TryUnpack(byte[] buf, int size, out ServerHello packet)
        {
            if (size < 3 || buf[0] != (byte)ServerHello.Type)
            {
                packet = default;
                return(false);
            }
            int offset = 3;
            var cookie = BinaryUtil.ReadBytes(buf, size - offset, ref offset);

            packet = new ServerHello(buf[1], buf[2], cookie);
            return(true);
        }
        public void Read_ResultsAreExpected()
        {
            //Arrange
            var messageBytes     = Utils.ParseHexString(GetMessageHexString());
            var record           = new TlsRecord();
            var message          = new ServerHello();
            var keyShareEntry    = new KeyShareEntry();
            var supportedVersion = new ProtocolVersion();

            //Act
            var cursor = new MemoryCursor(messageBytes);
            var result = TlsRecord.TryParse(cursor, RecordType.Handshake, out record);

            using (record.Payload.SetCursor(cursor))
            {
                result &= ServerHello.TryParse(cursor, out message);

                using (message.Payload.SetCursor(cursor))
                {
                    result &= cursor.TryParseKeyShare(out var keyShareBuffer);
                    using (keyShareBuffer.SetCursor(cursor))
                    {
                        keyShareEntry = KeyShareEntry.Parse(cursor);
                    }

                    result &= cursor.TryParseSupportedVersion(out var supportedVersionBuffer);
                    using (supportedVersionBuffer.SetCursor(cursor))
                    {
                        supportedVersion = ProtocolVersion.Parse(cursor);
                    }

                    result &= cursor.IsEnd();
                }

                result &= cursor.IsEnd();
            }

            result &= cursor.IsEnd();

            //Assert
            Assert.True(result);
            Assert.Equal(RecordType.Handshake, record.Type);
            Assert.Equal(ProtocolVersion.Tls12, record.ProtocolVersion);
            Assert.Equal(HandshakeRandom.Parse(GetBytesOfRandom()), message.Random);
            Assert.Equal(SessionId.Parse(GetBytesOfSessionId()), message.SessionId);
            Assert.Equal(Cipher.TLS_AES_128_GCM_SHA256, message.Cipher);
            Assert.Equal(NamedGroup.X25519, keyShareEntry.Group);
            Assert.True(GetBytesOfPublicKey().AsSpan().SequenceEqual(keyShareEntry.Key.Read(cursor).Span));
            Assert.Equal(ProtocolVersion.Tls13, supportedVersion);
        }
Example #10
0
    void ProcessMessage(ServerMessage msg)
    {
        ServerMessageType msgType = msg.MsgType;

        switch (msgType)
        {
        case ServerMessageType.ServerHello:
            ServerHello serverHello = msg.GetMsg(new ServerHello());
            ProcessServerHello(serverHello);
            break;

        case ServerMessageType.ServerWorldState:
            ServerWorldState serverWorldState = msg.GetMsg(new ServerWorldState());
            ReplicateState(serverWorldState);
            break;
        }
    }
Example #11
0
        public static Record Create(Span <byte> bytes)
        {
            if (bytes == null)
            {
                throw new ArgumentNullException(nameof(bytes));
            }
            if (bytes.Length < 5)
            {
                throw new ArgumentException("A minimum of 5 bytes is needed to parse a TLS record.");
            }

            RecordContentTypes type = (RecordContentTypes)bytes[0];

            switch (type)
            {
            case RecordContentTypes.Alert:
                AlertProtocol alertRecord = new AlertProtocol();
                alertRecord.Deserialize(bytes);
                return(alertRecord);

            case RecordContentTypes.ApplicationData:
                throw new NotImplementedException("Can't yet handle 'Application Data' content.");

            case RecordContentTypes.ChangeCipherSpec:
                throw new NotImplementedException("Can't yet handle 'Change Cipher Spec' content.");

            case RecordContentTypes.Handshake:
                HandshakeType handshakeType = (HandshakeType)bytes[5];
                switch (handshakeType)
                {
                case HandshakeType.ServerHello:
                    ServerHello serverHello = new ServerHello();
                    serverHello.Deserialize(bytes);
                    return(serverHello);

                default:
                    throw new NotImplementedException($"Can't yet handle 'Handshake' content of type '{handshakeType}'.");
                }

            default:
                throw new ArgumentException($"Unknown record content type: {type}");
            }
        }
Example #12
0
        private async Task Process(ServerHello m)
        {
            conn.SelectedCipherSuite = m.CipherSuite;

            if (m.KeyShare == null || m.KeyShare.Group != conn.MyKeyShare.Group)
            {
                return;
            }

            if (m.KeyShare.Group == Messages.Extensions.NamedGroup.secp256r1)
            {
                var sharedPub     = CryptoHelper.PublicKeyFromBytes(m.KeyShare.KeyExchange);
                var shared_secret = CryptoHelper.CalculateSharedKey(conn.MyKey, sharedPub);

                //var shared_secret = new byte[0]; //CryptoHelper.ComputeSha256Hash(ecdhe.DeriveKeyMaterial(theirKey));
                var hello_hash = conn.GetHashOfProcessedMessage();
                var zero_key   = "0000000000000000000000000000000000000000000000000000000000000000".ToByteArrayFromHex();

                AronParker.Hkdf.Hkdf hkdf = new AronParker.Hkdf.Hkdf(HashAlgorithmName.SHA256);

                var early_secret     = hkdf.Extract(zero_key, new byte[] { 0 });
                var empty_hash       = CryptoHelper.ComputeSha256Hash(new byte[] { });
                var derived_secret   = CryptoHelper.ExpandTLSLabel(hkdf, early_secret, CryptoHelper.DERIVED_LABEL, empty_hash, 32);
                var handshake_secret = hkdf.Extract(shared_secret, derived_secret);
                var client_handshake_traffic_secret = CryptoHelper.ExpandTLSLabel(hkdf, handshake_secret, CryptoHelper.CLIENT_HANDSHAKE_LABEL, hello_hash, 32);
                var server_handshake_traffic_secret = CryptoHelper.ExpandTLSLabel(hkdf, handshake_secret, CryptoHelper.SERVER_HANDSHAKE_LABEL, hello_hash, 32);

                //var masterKey = ecdhe.DeriveKeyTls(theirKey, MASTER_SECRET_LABEL, seed);
                //master_secret = PRF(premasterKey, "master secret", ClientHello.random + ServerHello.random)
                //var keyData = EncryptionKeys.Hkdf256.Expand(premasterKey, 96, seed);

                conn.CipherUpdated(new CipherUpdateDetail()
                {
                    State        = EncryptionState.Handshake,
                    ClientSecret = client_handshake_traffic_secret,
                    ServerSecret = server_handshake_traffic_secret,
                    CipherSuite  = conn.SelectedCipherSuite,
                });
            }

            await Task.Yield();
        }
Example #13
0
        private void HandleClientHello(byte[] message)
        {
            var clientHello = _serializer.Deserialize <ClientHello>(message);
            var session     = _sessionCache.NewSession();
            var random      = TLS12.GetRandom();

            session.ServerRandom = random;
            session.ClientRandom = clientHello.Random;
            session.RSAPublicPem = clientHello.RSAPublicPem;
            var serverHello = new ServerHello
            {
                SessionId    = session.Id,
                Random       = random,
                RSAPublicPem = _rsa.PublicPem
            };
            var response = new SecurityLayerMessage
            {
                Type = SecurityMessageType.ServerHello,
                Data = _serializer.Serialize <ServerHello>(serverHello)
            };
            var responseBytes = _serializer.Serialize <SecurityLayerMessage>(response);

            Send(responseBytes);
        }
Example #14
0
        private bool FullProtocolFromX509(ScpConfig.EncryptionMode encryptionMode, out byte[] symmetricKey, out MockedSecretarium secretarium)
        {
            // Client keys
            Assert.IsTrue(ScpConfigHelper.TryLoad("test.x509.json", out ScpConfig config));
            Assert.IsTrue(config.TryGetECDsaKey(out ECDsaCng clientECDsaKeyCng, "SecretariumTestClient256"));
            var clientPub = clientECDsaKeyCng.ExportPublicKeyRaw();

            // Client Hello
            var clientEph    = ECDHHelper.CreateCngKey();
            var clientEphCng = ECDHHelper.CreateECDiffieHellmanCngSha256(clientEph);
            var clientEphPub = clientEphCng.PublicKey();
            var clientHello  = clientEphPub;

            Assert.IsTrue(ClientHello.Parse(clientHello, out ClientHello clientHelloObj));

            // Server Hello
            secretarium = new MockedSecretarium(encryptionMode);
            secretarium.GetServerHello(clientHello, out byte[] serverHello);
            Assert.IsTrue(ServerHello.Parse(serverHello, 18, out ServerHello serverHelloObj));

            // Client ClientProofOfWork
            Assert.IsTrue(DiffieHellmanHelper.ComputeProofOfWork(serverHelloObj.proofOfWorkDetails, out byte[] proofOfWork));
            var clientProofOfWork = ByteHelper.Combine(proofOfWork.ExtendTo(32), MockedSecretarium.GenesisPubKey);

            Assert.IsTrue(ClientProofOfWork.Parse(clientProofOfWork, out ClientProofOfWork clientProofOfWorkObj));

            // Server Identity
            secretarium.GetServerIdentity(clientProofOfWork, out byte[] serverIdentity);
            Assert.IsTrue(ServerIdentity.Parse(serverIdentity, out ServerIdentity serverIdentityObj));

            // Client computes symmetric key
            symmetricKey = DiffieHellmanHelper.GetSymmetricKey(
                clientEphCng, serverIdentityObj.ephDHKey, serverIdentityObj.preMasterSecret);

            // Client Proof Of Identity
            var nonce                 = ByteHelper.GetRandom(32);
            var nonceSigned           = clientECDsaKeyCng.SignData(nonce);
            var clientProofOfIdentity = ByteHelper.Combine(nonce, clientEphPub, clientPub, nonceSigned);

            Assert.IsTrue(ClientProofOfIdentity.Parse(clientProofOfIdentity, out ClientProofOfIdentity clientProofOfIdentityObj));

            // Client Encrypts Client Proof Of Identity
            var ivOffset = ByteHelper.GetRandom(16);
            var encryptedClientProofOfIdentity = encryptionMode == ScpConfig.EncryptionMode.AESCTR
                ? clientProofOfIdentity.AesCtrEncrypt(symmetricKey, ivOffset)
                : clientProofOfIdentity.AesGcmEncryptWithOffset(symmetricKey, ivOffset);
            var encryptedClientProofOfIdentityWithIvOffset = ByteHelper.Combine(ivOffset, encryptedClientProofOfIdentity);

            // Server Checks And Sends Proof Of Identity
            Assert.IsTrue(secretarium.GetServerProofOfIdentity(
                              encryptedClientProofOfIdentityWithIvOffset, out byte[] encryptedServerProofOfIdentity));

            // Client Decrypts Server Proof Of Identity
            ivOffset = encryptedServerProofOfIdentity.Extract(0, 16);
            var serverProofOfIdentity = encryptionMode == ScpConfig.EncryptionMode.AESCTR
                ? encryptedServerProofOfIdentity.Extract(16).AesCtrDecrypt(symmetricKey, ivOffset)
                : encryptedServerProofOfIdentity.Extract(16).AesGcmDecryptWithOffset(symmetricKey, ivOffset);

            Assert.IsTrue(ServerProofOfIdentity.Parse(serverProofOfIdentity, out ServerProofOfIdentity serverProofOfIdentityObj));

            // Client Checks Server Proof Of Idendity
            var msg = "Hey you! Welcome to Secretarium!".ToBytes();
            var secretariumECDsaCng = ECDsaHelper.ImportPublicKey(serverIdentityObj.publicKey);

            Assert.IsTrue(secretariumECDsaCng.VerifyData(
                              ByteHelper.Combine(serverProofOfIdentityObj.nonce, msg), serverProofOfIdentityObj.welcomeSigned));

            return(true);
        }
Example #15
0
        private static void ParseServerHello(BytesSegment msg, ref ServerHello hello)
        {
            var cur = 0;

            if (msg[cur] != 2)
            {
                throw new Exception("Expected server hello (2), got " + msg[cur]);
            }
            cur++;
            var msgLength = msg[cur] << 16 | msg[cur + 1] << 8 | msg[cur + 2]; cur += 3;

            msg.SubSelf(4); cur = 0;

            hello.Version = (ushort)(msg[cur] << 8 | msg[cur + 1]); cur += 2;

            cur += 32;           // skip random
            cur += 1 + msg[cur]; // skip session_id
            cur += 2;            // skip cipher suite
            cur += 1;            // compression_methods
            if (cur >= msgLength)
            {
                throw new Exception("extensionsBegin >= msgLength");
            }

            var extensionsLength = msg[cur] << 8 | msg[cur + 1]; cur += 2;
            var extensionsEnd    = cur + extensionsLength;

            if (extensionsEnd > msgLength)
            {
                throw new Exception("extensionsEnd > msgLength");
            }
            while (cur < extensionsEnd)
            {
                var extType = (msg[cur] << 8 | msg[cur + 1]); cur += 2;
                var extLen  = (msg[cur] << 8 | msg[cur + 1]); cur += 2;
                var extEnd  = cur + extLen;
                if (extEnd > extensionsEnd)
                {
                    throw new Exception("extEnd > extensionsEnd");
                }
                if (extType == 0)   // server_name
                {
                    hello.SniUsed = true;
                }
                else if (extType == 16)     // ALPN
                {
                    var listLen = (msg[cur] << 8 | msg[cur + 1]); cur += 2;
                    var listEnd = cur + listLen;
                    if (listEnd > extEnd)
                    {
                        throw new Exception("alpnListEnd > extEnd");
                    }
                    if (cur < listEnd)   // read the first item only
                    {
                        var strLen = msg[cur++];
                        if (cur + strLen > listEnd)
                        {
                            throw new Exception("alpnStrEnd > nameListEnd");
                        }
                        hello.Alpn = Encoding.ASCII.GetString(msg.Bytes, msg.Offset + cur, strLen);
                    }
                }
                else if (extType == 43)     // supported_versions
                {
                    if (extLen != 2)
                    {
                        throw new Exception("supported_versions extLen != 2");
                    }
                    var ver = (ushort)(msg[cur] << 8 | msg[cur + 1]); cur += 2;
                    hello.Version = ver;
                }
                cur = extEnd;
            }
            return;
        }
Example #16
0
        //[Fact]
        public void Test1()
        {
            var buff  = new byte[PacketBuffer.MaxPacketSize];
            var pBuff = Utils.ParseHexString("060040f1010000ed0303ebf8fa56f12939b9584a3896472ec40bb863cfd3e86804fe3a47f06a2b69484c00000413011302010000c000000010000e00000b6578616d706c652e636f6dff01000100000a00080006001d0017001800100007000504616c706e000500050100000000003300260024001d00209370b2c9caa47fbabaf4559fedba753de171fa71f50f1ce15d43e994ec74d748002b0003020304000d0010000e0403050306030203080408050806002d00020101001c00024001ffa500320408ffffffffffffffff05048000ffff07048000ffff0801100104800075300901100f088394c8f03e51570806048000ffff");
            var hBuff = Utils.ParseHexString("c3ff000020088394c8f03e5157080000449e00000002");

            Array.Resize(ref pBuff, 1162);
            Array.Copy(hBuff, buff, hBuff.Length);
            Array.Copy(pBuff, 0, buff, hBuff.Length, pBuff.Length);
            Array.Resize(ref buff, hBuff.Length + pBuff.Length);

            var encryptedBuff = new byte[PacketBuffer.MaxPacketSize];
            var aead          = Cipher.TLS_AES_128_GCM_SHA256.CreateAead(Utils.ParseHexString("6b26114b9cba2b63a9e8dd4f"), Utils.ParseHexString("175257a31eb09dea9366d8bb79ad80ba"));
            //var token = aead.StartEncryption(pBuff, encryptedBuff);
            //token.UseSequenceNumber(2);
            //token.UseAssociatedData(hBuff);
            //aead.Finish(token);
            //var encryptedHex = Utils.ToHexString(token.Result.ToArray());

            var c    = new MemoryCursor(buff);
            var res1 = InitialPacket.TryParse(c, out var p);

            using (p.Payload.SetCursor(c))
            {
                var res2 = CryptoFrame.TryParse(c, out var f);
            }
            var res3 = c.IsEnd();

            var buffer = new byte[PacketBuffer.MaxPacketSize];
            var cursor = new MemoryCursor(buffer);

            using (InitialPacket.StartWriting(
                       cursor,
                       PacketVersion.CreateByDraft(29),
                       PacketConnectionId.Generate(),
                       PacketConnectionId.Generate(),
                       PacketNumber.Initial,
                       PacketToken.Empty))
            {
                using (CryptoFrame.StartWriting(cursor, 0))
                {
                    using (ClientHello.StartWriting(cursor, HandshakeRandom.Generate(), Cipher.Supported, SessionId.Generate()))
                    {
                        using (cursor.StartSupportedGroupsWriting())
                        {
                            foreach (var group in NamedGroup.Supported.Span)
                            {
                                group.WriteBytes(cursor);
                            }
                        }

                        using (cursor.StartSignatureAlgorithmsWriting())
                        {
                            foreach (var scheme in SignatureScheme.Supported.Span)
                            {
                                scheme.WriteBytes(cursor);
                            }
                        }

                        using (cursor.StartKeySharesWriting())
                        {
                            using (KeyShareEntry.StartWriting(cursor, NamedGroup.X25519))
                            {
                                Utils.ParseHexString("358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254").CopyTo(cursor);
                            }
                        }

                        using (cursor.StartPskKeyExchangeModesWriting())
                        {
                            PskKeyExchangeMode.PskDheKe.WriteBytes(cursor);
                        }

                        using (cursor.StartSupportedVersionsWriting())
                        {
                            ProtocolVersion.Tls13.WriteBytes(cursor);
                        }

                        cursor.StartTransportParametersWriting().Dispose();
                    }

                    for (int i = 0; i < 1000; i++)
                    {
                        PaddingFrame.WriteBytes(cursor);
                    }
                }
            }

            var t = Utils.ParseHexString("c0ff00001d08d0076f25b832934b0841f39c4f6381d72e0044ba00060041060100010203036e3828a258f4a7488d105acd6da670a41b28c2b601c58c4530486df585ec54a6000006130213011303010000d30033004700450017004104e46de65fb3e4fa258e1f03c551fa6a4507411e09bdc32e4dc597084db1852caf9d5b783243ebc748bf644ca31e108f4fdea2c19ae3c94ad99714dfa38a6a244500000021001f00001c68747470332d746573742e6c6974657370656564746563682e636f6d0010000800060568332d3239002b0003020304000d000a00080804040304010201000a000600040017001dffa5002d050480004000070480004000040480008000080101090103010267100e0104030245c00f0841f39c4f6381d72e002d000302000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");

            var client   = new UdpClient(0);
            var endPoint = new IPEndPoint(IPAddress.Parse("52.55.120.73"), 443);

            client.Send(t, t.Length, endPoint);

            IPEndPoint ep       = null;
            var        response = client.Receive(ref ep);

            var h1 = Utils.ToHexString(response);

            cursor = new MemoryCursor(response);

            var result = InitialPacket.TryParse(cursor, out var packet);

            using (packet.Payload.SetCursor(cursor))
            {
                var h2 = Utils.ToHexString(cursor.PeekEnd().ToArray());

                CryptoFrame.TryParse(cursor, out var cryptoFrame);

                using (cryptoFrame.Data.SetCursor(cursor))
                {
                    ServerHello.TryParse(cursor, out var sh);
                }
            }

            Assert.True(true);

            //var snBuff = new byte[100];
            //var snIter = snBuff.AsSpan();
            //ServerNameExtension.WriteHostName(ref snIter, "example.ulfheim.net");
            //var snResult = Parse(snBuff.AsSpan().Slice(0, snBuff.Length - snIter.Length).ToArray());

            //var keyShareBuff = new byte[1000];
            //var keyShareSpan = keyShareBuff.AsSpan();
            //var privateKey = Parse("202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f");
            //var publicKey = NamedGroup.X25519.GeneratePublicKey(privateKey);
            //KeyShareExtension.WriteClientEntry(ref keyShareSpan, NamedGroup.X25519, publicKey);
            //var keyShareData = Parse(keyShareBuff.AsSpan().Slice(0, keyShareBuff.Length - keyShareSpan.Length).ToArray());

            //var secret = Parse("ff0e5b965291c608c1e8cd267eefc0afcc5e98a2786373f0db47b04786d72aea");
            //var hash = Parse("22844b930e5e0a59a09d5ac35fc032fc91163b193874a265236e568077378d8b");
            //var expected = Parse("976017a77ae47f1658e28f7085fe37d149d1e9c91f56e1aebbe0c6bb054bd92b");

            //var verifyData = Hash.Sha256.CreateVerifyData(secret, hash);
            //var result = verifyData.Span.SequenceEqual(expected);

            //var bytes = GetData();

            //InitialPacket.TryParse(bytes, out var initial, out var remainings);

            //CryptoFrame.TryParse(initial.Payload, out var crypto, out var afterCrypto);

            //ClientHello.TryParse(crypto.Data, out var hello, out var afterHello);

            //KeyShareExtension.TryParse(hello.Payload, out var keyShare, out var afterKeyShare);

            //var unknownBytes = UnknownExtension.SliceBytes(afterKeyShare, out var afterUnknown);

            //AlpnExtension.TryParse(afterUnknown, out var alpn, out var afterAlpn);

            //SupportedVersionExtension.TryParse(afterAlpn, out var supportedVersion, out var afterSupportedVersion);

            //SignatureAlgorithmsExtension.TryParse(afterSupportedVersion, out var signatureAlgorithms, out var afterSignatureAlgorithms);

            //SupportedGroupsExtension.TryParse(afterSignatureAlgorithms, out var supportedGroups, out var afterSupportedGroups);

            //TransportParametersExtension.TryParse(afterSupportedGroups, out var transportParametersExtension, out var afterTransportParametersExtension);

            //PskKeyExchangeModesExtension.TryParse(afterTransportParametersExtension, out var pskKeyExchangeModes, out var afterPsk);

            ////----------------------------------------------------------------

            //var buffer = new byte[65000];
            //var destination = buffer.AsSpan();

            //var initialContext = InitialPacket.StartWriting(ref destination, initial.Version, initial.DestinationConnectionId, initial.SourceConnectionId, initial.Number, initial.Token);
            //var cryptoContext = CryptoFrame.StartWriting(ref destination, 0);
            //var clientHelloContext = ClientHello.StartWriting(ref destination, hello.Random, hello.CipherSuite, hello.SessionId);

            //keyShare.WriteBytes(ref destination);

            //unknownBytes.Span.CopyTo(destination);
            //destination = destination.Slice(unknownBytes.Length);

            //alpn.WriteBytes(ref destination);

            //supportedVersion.WriteBytes(ref destination);

            //signatureAlgorithms.WriteBytes(ref destination);

            //supportedGroups.WriteBytes(ref destination);

            //var transportParametersContext = TransportParametersExtension.StartWriting(ref destination);
            //transportParametersExtension.Data.Span.CopyTo(destination);
            //destination = destination.Slice(transportParametersExtension.Data.Length);
            //transportParametersContext.Complete(ref destination);

            //pskKeyExchangeModes.WriteBytes(ref destination);

            //clientHelloContext.Complete(ref destination);
            //cryptoContext.Complete(ref destination);

            //for (int i = 0; i < 1000; i++)
            //{
            //    PaddingFrame.WriteBytes(ref destination);
            //}

            //initialContext.Complete(ref destination);

            ////----------------------------------------------------------------

            //InitialPacket.TryParse(buffer.ToArray(), out var initial1, out var remainings1);

            //CryptoFrame.TryParse(initial1.Payload, out var crypto1, out var afterCrypto1);

            //ClientHello.TryParse(crypto1.Data, out var hello1, out var afterHello1);

            //KeyShareExtension.TryParse(hello1.Payload, out var keyShare1, out var afterKeyShare1);

            //var unknownBytes1 = UnknownExtension.SliceBytes(afterKeyShare1, out var afterUnknown1);

            //AlpnExtension.TryParse(afterUnknown1, out var alpn1, out var afterAlpn1);

            //SupportedVersionExtension.TryParse(afterAlpn1, out var supportedVersion1, out var afterSupportedVersion1);

            //SignatureAlgorithmsExtension.TryParse(afterSupportedVersion1, out var signatureAlgorithms1, out var afterSignatureAlgorithms1);

            //SupportedGroupsExtension.TryParse(afterSignatureAlgorithms1, out var supportedGroups1, out var afterSupportedGroups1);

            //TransportParametersExtension.TryParse(afterSupportedGroups1, out var transportParametersExtension1, out var afterTransportParametersExtension1);

            //PskKeyExchangeModesExtension.TryParse(afterTransportParametersExtension1, out var pskKeyExchangeModes1, out var afterPsk1);

            //var client = DatagramChannel.Start(opt =>
            //{
            //    opt.ListeningPoint = new IPEndPoint(IPAddress.Any, 50000);
            //});

            //var addr = Dns.GetHostAddresses("litespeedtech.com"); //443
            ////var addr = Dns.GetHostAddresses("test.privateoctopus.com"); //4433
            ////var addr = Dns.GetHostAddresses("quant.eggert.org"); //4433
            ////var addr = Dns.GetHostAddresses("f5quic.com"); //4433

            //var dgram = new Datagram().WithAddress(addr[0]).WithPort(443).WithBuffer(buffer.ToArray());

            //client.Writer.TryWrite(dgram);

            //var response = client.Reader.ReadAsync().AsTask().Result;
        }
Example #17
0
        private byte[] GetByteMessage(ServerHello serverHello)
        {
            var result = serverHello.ServerRandom.Concat(serverHello.PublicKey.X).Concat(serverHello.PublicKey.Y).ToArray();

            return(result);
        }
        void ProcessHandshake()
        {
            ClientHello clientHello = _recordLayer.Read() as ClientHello;

            if (clientHello == null)
            {
                throw new Exception();
            }
            Console.WriteLine("[TLSServer] Receive ClientHello Version: {0}", clientHello.Version);
            Console.WriteLine("[TLSServer] CipherSuites");
            for (int i = 0; i < clientHello.CipherSuites.Length; i++)
            {
                Console.WriteLine("  {0}", clientHello.CipherSuites[i]);
            }
            CipherSuite selected = _selector.Select(clientHello.CipherSuites);

            Console.WriteLine("[TLSServer] CipherSuite Selected. {0}", selected);
            if (selected == CipherSuite.NONE)
            {
                // Alertを送るべき?
                throw new Exception();
            }
            CipherSuiteInfo selectedInfo = SupportedCipherSuites.GetSuiteInfo(selected);

            _sparams.SetVersion(clientHello.Version);
            _sparams.SetCipherSuite(selected, _signAlgo);
            _sparams.ClientRandom        = clientHello.Random;
            _recordLayer.ProtocolVersion = clientHello.Version;

            byte[]      serverRandom     = new byte[RandomData.Size];
            Extension[] serverExtensions = null;
            if (selectedInfo.IsECC)
            {
                serverExtensions = new Extension[] { new Extension(ExtensionType.EcPointFormats, new byte[] { 1, 0 }) }
            }
            ;
            RandomData.CreateRandomData(serverRandom, 0);
            _sparams.ServerRandom = serverRandom;
            ServerHello serverHello = new ServerHello(clientHello.Version, serverRandom, Utility.EmptyByteArray, selected, CompressionMethod.Null, serverExtensions);

            _recordLayer.Write(serverHello);

            Certificate serverCert = new Certificate(_certs);

            _recordLayer.Write(serverCert);

            if (Utility.IsNeedServerKeyExchangeMessage(_states.SecurityParameters.KeyExchangeAlgorithm))
            {
                ServerKeyExchange serverExchange = new ServerKeyExchange(_sparams);
                _recordLayer.Write(serverExchange);
            }

            _recordLayer.Write(new ServerHelloDone());

            TLSMessage        msg            = _recordLayer.Read();
            ClientKeyExchange clientExchange = (ClientKeyExchange)msg;

            clientExchange.ComputeServerMasterSecret(_sparams);
            Console.WriteLine("MasterSecret");
            Utility.Dump(_sparams.MasterSecret);
            _sparams.ComputeKeyBlock();

            ChangeCipherSpec changeCipherSpec = (ChangeCipherSpec)_recordLayer.Read();

            _recordLayer.EnableReceiveCipher(_sparams.CreateServerDecryptor(), _sparams.CreateClientWriteHMAC());

            Finished finished = (Finished)_recordLayer.Read();

            Console.WriteLine("VerifyData");
            Utility.Dump(finished.VerifyData);
            Console.WriteLine("Computed VerifyData");
            byte[] verifyData = _sparams.ComputeFinishedVerifyData(false);
            Utility.Dump(verifyData);
            if (!Utility.Equals(finished.VerifyData, 0, verifyData, 0, verifyData.Length))
            {
                throw new Exception();
            }

            _recordLayer.Write(ChangeCipherSpec.Instance);
            _recordLayer.EnableSendCipher(_sparams.CreateServerEncryptor(), _sparams.CreateServerWriteHMAC());
            _recordLayer.ComputeHandshakeHash(true);
            verifyData = _sparams.ComputeFinishedVerifyData(true);
            Console.WriteLine("Finished VerifyData");
            Utility.Dump(verifyData);
            finished = new Finished(_recordLayer.ProtocolVersion, verifyData);
            _recordLayer.Write(finished);
        }