protected override async void HandleClientHelloWithCookieRequest(ClientHelloWithCookieRequest packet, MessageOrigin origin)
        {
            var fakeSignature = PacketEncryptionLayer.GenerateRandom(128);

            if (!serverRandoms.ContainsKey(origin.endPoint))
            {
                serverRandoms[origin.endPoint] = PacketEncryptionLayer.GenerateRandom(32);
            }
            if (!serverKeys.ContainsKey(origin.endPoint))
            {
                serverKeys[origin.endPoint] = await _keysTask;
            }

            SendReliableResponse(1u, origin.endPoint, packet, ServerHelloRequest.pool.Obtain().Init(serverRandoms[origin.endPoint], serverKeys[origin.endPoint].publicKey, fakeSignature));
            SendReliableResponse(1u, origin.endPoint, packet.certificateResponseId, ServerCertificateRequest.pool.Obtain().Init(new List <byte[]>
            {
                serverRandoms[origin.endPoint]
            }));
            packet.Release();
        }
Example #2
0
        public async Task <ServerHelloRequest> ClientHelloWithCookie(ISession session, ClientHelloWithCookieRequest request)
        {
            _logger.Verbose(
                $"Handling {nameof(ClientHelloWithCookieRequest)} " +
                $"(CertificateResponseId={request.CertificateResponseId}, " +
                $"Random='{BitConverter.ToString(request.Random)}', " +
                $"Cookie='{BitConverter.ToString(request.Cookie)}')."
                );
            if (!request.Cookie.SequenceEqual(session.Cookie))
            {
                _logger.Warning(
                    $"Session sent {nameof(ClientHelloWithCookieRequest)} with a mismatching cookie " +
                    $"(EndPoint='{session.EndPoint}', " +
                    $"Cookie='{BitConverter.ToString(request.Cookie)}', " +
                    $"Expected='{BitConverter.ToString(session.Cookie ?? new byte[0])}')."
                    );
                return(null);
            }
            if (!request.Random.SequenceEqual(session.ClientRandom))
            {
                _logger.Warning(
                    $"Session sent {nameof(ClientHelloWithCookieRequest)} with a mismatching client random " +
                    $"(EndPoint='{session.EndPoint}', " +
                    $"Random='{BitConverter.ToString(request.Random)}', " +
                    $"Expected='{BitConverter.ToString(session.ClientRandom ?? new byte[0])}')."
                    );
                return(null);
            }

            // Generate a server random
            session.ServerRandom = _randomProvider.GetRandom();

            // Generate a key pair
            var keyPair = _diffieHellmanService.GetECKeyPair();

            session.ServerPrivateKeyParameters = keyPair.PrivateKeyParameters;

            // Generate a signature
            var certificate = _certificateProvider.GetCertificate();
            var signature   = MakeSignature(session.ClientRandom, session.ServerRandom, keyPair.PublicKey);

            await _messageDispatcher.Send(session, new ServerCertificateRequest()
            {
                RequestId    = session.GetNextRequestId(),
                ResponseId   = request.CertificateResponseId,
                Certificates = new List <byte[]>()
                {
                    certificate.RawData
                }
            });

            return(new ServerHelloRequest()
            {
                Random = session.ServerRandom,
                PublicKey = keyPair.PublicKey,
                Signature = signature
            });
        }