/// <summary> /// Creates a new Nonce value. /// </summary> /// <param name="ClientSender">If the client is the sender (true), or the server (false).</param> /// <param name="State">Endpoint state.</param> /// <returns>New nonce value.</returns> protected byte[] CreateNonce(bool ClientSender, EndpointState State) { // Nonce calculation defind in RFC 5288, §3. byte[] Nonce = new byte[12]; if (ClientSender) { Array.Copy(State.client_write_IV, 0, Nonce, 0, this.fixedIvLength); } else { Array.Copy(State.server_write_IV, 0, Nonce, 0, this.fixedIvLength); } ulong c = State.nonceCount++; int Pos = 12; int i; for (i = 0; i < 8; i++) { Nonce[--Pos] = (byte)c; c >>= 8; } return(Nonce); }
/// <summary> /// Verifies the claims in a finished message. /// </summary> /// <param name="VerifyData">Verify data in finished message.</param> /// <param name="State">Endpoint state.</param> /// <returns>If the <paramref name="VerifyData"/> is valid or not.</returns> public virtual bool VerifyFinished(byte[] VerifyData, EndpointState State) { if (State.masterSecret == null) { return(false); } string Label; byte[] HandshakeHash; byte[] VerifyData0; if (State.isClient) { Label = "server finished"; State.CalcServerHandshakeHash(); HandshakeHash = State.serverHandshakeHash; } else { Label = "client finished"; State.CalcClientHandshakeHash(); HandshakeHash = State.clientHandshakeHash; } VerifyData0 = this.PRF(State.masterSecret, Label, HandshakeHash, 12); return(DtlsEndpoint.AreEqual(VerifyData0, VerifyData)); }
private async Task WaitForStateAsync(EndpointState state, CancellationToken cancellationToken = default) { using var signal = new SemaphoreSlim(0); StateChanged += OnStateChanged; try { if (_stateIterator.Current == state) { return; } await signal.WaitAsync(cancellationToken) .ConfigureAwait(false); } finally { StateChanged -= OnStateChanged; } void OnStateChanged( EndpointState changedState) { if (changedState == state) { signal.Release(); } } }
protected override Task PublishStatusAsync(CallbackEvent callbackEvent) { const EndpointState endpointState = EndpointState.Disconnected; var command = new UpdateEndpointStatusAndRoomCommand(SourceConference.Id, SourceEndpoint.Id, endpointState, null); return(CommandHandler.Handle(command)); }
/// <summary> /// Encrypts data according to the cipher settings. /// </summary> /// <param name="Data">Data to encrypt.</param> /// <param name="Header">Record header.</param> /// <param name="Start">Start offset of header.</param> /// <param name="State">Endpoint state.</param> /// <returns>Encrypted data.</returns> public override byte[] Encrypt(byte[] Data, byte[] Header, int Start, EndpointState State) { lock (this.aesCcm) { byte[] AeadCipher; byte[] CipherText; byte[] Nonce; byte[] AD = this.GetAssociatedData(Header, Start); if (State.isClient) { Nonce = this.CreateNonce(true, State); CipherText = this.aesCcm.Encrypt(Data, AD, Nonce, State.client_write_key); } else { Nonce = this.CreateNonce(false, State); CipherText = this.aesCcm.Encrypt(Data, AD, Nonce, State.server_write_key); } // On AEAD ciphers, see RFC 5246, §6.2.3.3 int RecordIvLength = Nonce.Length - this.fixedIvLength; int N = CipherText.Length; AeadCipher = new byte[RecordIvLength + N]; Array.Copy(Nonce, this.fixedIvLength, AeadCipher, 0, RecordIvLength); Array.Copy(CipherText, 0, AeadCipher, RecordIvLength, N); return(AeadCipher); } }
private void CalcMasterSecret(EndpointState State) { if (State.credentials is PresharedKey Psk) { ushort N = (ushort)Psk.Key.Length; byte[] PremasterSecret = new byte[4 + (N << 1)]; PremasterSecret[0] = (byte)(N >> 8); PremasterSecret[1] = (byte)N; PremasterSecret[N + 2] = (byte)(N >> 8); PremasterSecret[N + 3] = (byte)N; if (N > 0) { Array.Copy(Psk.Key, 0, PremasterSecret, N + 4, N); } // RFC 5246, §8.1, Computing the Master Secret: this.SetMasterSecret(this.PRF(PremasterSecret, "master secret", Concat(State.clientRandom, State.serverRandom), 48), State); PremasterSecret.Initialize(); } else { State.masterSecret = null; State.client_write_MAC_key = null; State.server_write_MAC_key = null; State.client_write_key = null; State.server_write_key = null; State.client_write_IV = null; State.server_write_IV = null; } }
internal EndpointStateNode( EndpointState state, IReadOnlyDictionary <EndpointState, EndpointStateNode> branches) { _branches = branches; State = state; }
/// <summary> /// Sends the Client Key Exchange message flight. /// </summary> /// <param name="Endpoint">Endpoint.</param> /// <param name="State">Endpoint state.</param> public override void SendClientKeyExchange(DtlsEndpoint Endpoint, EndpointState State) { this.CalcMasterSecret(State); // Sends the Client Key Exchange message for Pre-shared key ciphers, // as defined in §2 of RFC 4279: https://tools.ietf.org/html/rfc4279 if (State.credentials is PresharedKey Psk) { ushort N = (ushort)Psk.Identity.Length; byte[] ClientKeyExchange = new byte[2 + N]; ClientKeyExchange[0] = (byte)(N >> 8); ClientKeyExchange[1] = (byte)N; Array.Copy(Psk.Identity, 0, ClientKeyExchange, 2, N); Endpoint.SendHandshake(HandshakeType.client_key_exchange, ClientKeyExchange, true, true, State); // RFC 5246, §7.1, Change Cipher Spec Protocol: Endpoint.SendRecord(ContentType.change_cipher_spec, new byte[] { 1 }, true, true, State); Endpoint.ChangeCipherSpec(State, true); this.SendFinished(Endpoint, State, true); } }
protected internal void _endpoint_state_cb(EndpointState msg) { lock (this) { _last_endpoint_state = _stopwatch.ElapsedMilliseconds; if (!msg.valid) { _endpoint_pose = null; _endpoint_vel = null; return; } var p = new Pose(); p.orientation.w = msg.pose.orientation.w; p.orientation.x = msg.pose.orientation.x; p.orientation.y = msg.pose.orientation.y; p.orientation.z = msg.pose.orientation.z; p.position.x = msg.pose.position.x; p.position.y = msg.pose.position.y; p.position.z = msg.pose.position.z; var v = new SpatialVelocity(); v.angular.x = msg.twist.angular.x; v.angular.y = msg.twist.angular.y; v.angular.z = msg.twist.angular.z; v.linear.x = msg.twist.linear.x; v.linear.y = msg.twist.linear.y; v.linear.z = msg.twist.linear.z; _endpoint_pose = new Pose[] { p }; _endpoint_vel = new SpatialVelocity[] { v }; } }
public async Task Should_update_existing_endpoint_with_new_status_and_room() { var conference1 = new ConferenceBuilder() .WithEndpoint("DisplayName", "*****@*****.**").Build(); var seededConference = await TestDataManager.SeedConference(conference1); var endpointId = conference1.Endpoints.First().Id; const EndpointState status = EndpointState.Connected; const RoomType room = RoomType.HearingRoom; TestContext.WriteLine($"New seeded conference id: {seededConference.Id}"); _newConferenceId = seededConference.Id; var command = new UpdateEndpointStatusAndRoomCommand(_newConferenceId, endpointId, status, room); await _handler.Handle(command); Conference updatedConference; await using (var db = new VideoApiDbContext(VideoBookingsDbContextOptions)) { updatedConference = await db.Conferences.Include(x => x.Endpoints) .AsNoTracking().SingleOrDefaultAsync(x => x.Id == _newConferenceId); } var updatedEndpoint = updatedConference.GetEndpoints().Single(x => x.Id == endpointId); updatedEndpoint.State.Should().Be(status); updatedEndpoint.GetCurrentRoom().Should().Be(room); }
/// <summary> /// Allows the cipher to process any client key information sent by the DTLS client. /// </summary> /// <param name="Data">Binary data.</param> /// <param name="Offset">Offset where data begins.</param> /// <param name="State">Endpoint state.</param> /// <returns>New offset after operation.</returns> public override async Task <int> ClientKeyExchange(byte[] Data, int Offset, EndpointState State) { ushort N = Data[Offset++]; N <<= 8; N |= Data[Offset++]; byte[] Identity = new byte[N]; Array.Copy(Data, Offset, Identity, 0, N); Offset += N; string UserId = Encoding.UTF8.GetString(Identity); IUser User = await State.localEndpoint.Users.TryGetUser(UserId); if (!(User is null) && (State.localEndpoint.RequiredPrivilege is null || User.HasPrivilege(State.localEndpoint.RequiredPrivilege))) { string s; byte[] Key = null; if (!string.IsNullOrEmpty(s = User.PasswordHash)) { Key = Hashes.StringToBinary(s); } if (Key is null) { Key = Encoding.UTF8.GetBytes(User.PasswordHash); } State.credentials = new PresharedKey(Identity, Key); this.CalcMasterSecret(State); }
/// <summary> /// Sets the master secret for the session. /// </summary> /// <param name="Value">Master secret.</param> /// <param name="State">Endpoint state.</param> public virtual void SetMasterSecret(byte[] Value, EndpointState State) { State.masterSecret = Value; // Key calculation: RFC 5246 §6.3: byte[] KeyBlock = this.PRF(State.masterSecret, "key expansion", Concat(State.serverRandom, State.clientRandom), (uint)((this.macKeyLength + this.encKeyLength + this.fixedIvLength) << 1)); int Pos = 0; State.client_write_MAC_key = new byte[this.macKeyLength]; Array.Copy(KeyBlock, Pos, State.client_write_MAC_key, 0, this.macKeyLength); Pos += this.macKeyLength; State.server_write_MAC_key = new byte[this.macKeyLength]; Array.Copy(KeyBlock, Pos, State.server_write_MAC_key, 0, this.macKeyLength); Pos += this.macKeyLength; State.client_write_key = new byte[this.encKeyLength]; Array.Copy(KeyBlock, Pos, State.client_write_key, 0, this.encKeyLength); Pos += this.encKeyLength; State.server_write_key = new byte[this.encKeyLength]; Array.Copy(KeyBlock, Pos, State.server_write_key, 0, this.encKeyLength); Pos += this.encKeyLength; State.client_write_IV = new byte[this.fixedIvLength]; Array.Copy(KeyBlock, Pos, State.client_write_IV, 0, this.fixedIvLength); Pos += this.fixedIvLength; State.server_write_IV = new byte[this.fixedIvLength]; Array.Copy(KeyBlock, Pos, State.server_write_IV, 0, this.fixedIvLength); }
/// <summary> /// /// </summary> /// <param name="type"></param> private void Setup(BrowserType type) { if (state != EndpointState.Idle) { throw new EndpointException("Call Endpoint::Setup from an incompatible state : " + state.ToString()); } Log.Debug("Endpoint Setting up ..."); state = EndpointState.Setup; browserType = type; stopSignal = new ManualResetEvent(false); stopSignal.Reset(); requestQueueWorker = new Thread(RequestQueueJob) { IsBackground = false, Name = "Endpoint::requestQueueWorker" }; responseQueueWorker = new Thread(ResponseQueueJob) { IsBackground = false, Name = "Endpoint::responseQueueWorker" }; mainWorker = new Thread(MainJob) { IsBackground = false, Name = "Endpoint::mainWorker" }; }
public void should_update_status(EndpointState newState) { var endpoint = new Endpoint("old name", "*****@*****.**", "1234", "Defence Sol"); endpoint.State.Should().Be(EndpointState.NotYetJoined); endpoint.UpdateStatus(newState); endpoint.State.Should().Be(newState); }
public UpdateEndpointStatusAndRoomCommand(Guid conferenceId, Guid endpointId, EndpointState status, RoomType?room) { ConferenceId = conferenceId; EndpointId = endpointId; Status = status; Room = room; }
protected override Task PublishStatusAsync(CallbackEvent callbackEvent) { const EndpointState endpointState = EndpointState.Connected; const RoomType room = RoomType.WaitingRoom; var command = new UpdateEndpointStatusAndRoomCommand(SourceConference.Id, SourceEndpoint.Id, endpointState, room); return(CommandHandler.Handle(command)); }
public void Should_throw_conference_not_found_exception_when_conference_does_not_exist() { var conferenceId = Guid.NewGuid(); var endpointId = Guid.NewGuid(); const EndpointState status = EndpointState.Connected; var command = new UpdateEndpointStatusAndRoomCommand(conferenceId, endpointId, status, null); Assert.ThrowsAsync <ConferenceNotFoundException>(() => _handler.Handle(command)); }
public async Task ThenTheEndpointsStateShouldBe(EndpointState state) { await using var db = new VideoApiDbContext(_context.VideoBookingsDbContextOptions); var conf = await db.Conferences.Include(x => x.Endpoints) .SingleAsync(x => x.Id == _context.Test.Conference.Id); var endpoint = conf.GetEndpoints().First(x => x.Id == _context.Test.ParticipantId); endpoint.State.Should().Be(state); }
public void Should_map_user_response_to_court_rooms_account(EndpointState apiState, VHEndpointStatus expected) { var endpoint = new EndpointsResponseBuilder().WithStatus(apiState).Build(); var result = _sut.Map(endpoint, 1); result.Should().NotBeNull(); result.DisplayName.Should().Be(endpoint.DisplayName); result.Id.Should().Be(endpoint.Id); result.Status.ToString().Should().Be(endpoint.Status.ToString()); result.DefenceAdvocateUsername.Should().Be(endpoint.DefenceAdvocate); result.PexipDisplayName.Should().Be($"PSTN;{endpoint.DisplayName};{endpoint.Id}"); }
public bool TransitionTo(EndpointState state) { var current = _current; if (current.TryGetNext(state, out var next)) { return(Interlocked.CompareExchange( ref _current, next, current) == current); } return(false); }
public async Task Should_throw_exception_when_endpoint_does_not_exist() { var seededConference = await TestDataManager.SeedConference(); var endpointId = Guid.NewGuid(); const EndpointState status = EndpointState.Connected; TestContext.WriteLine($"New seeded conference id: {seededConference.Id}"); _newConferenceId = seededConference.Id; var command = new UpdateEndpointStatusAndRoomCommand(_newConferenceId, endpointId, status, null); Assert.ThrowsAsync <EndpointNotFoundException>(async() => await _handler.Handle(command)); }
/// <summary> /// Allows the cipher to process any server key information sent by the DTLS server. /// </summary> /// <param name="Data">Binary data.</param> /// <param name="Offset">Offset where data begins.</param> /// <param name="State">Endpoint state.</param> public override void ServerKeyExchange(byte[] Data, ref int Offset, EndpointState State) { // RFC 4279, §2: ushort Len = Data[Offset++]; Len <<= 8; Len |= Data[Offset++]; State.psk_identity_hint = new byte[Len]; Array.Copy(Data, Offset, State.psk_identity_hint, 0, Len); Offset += Len; }
/// <summary> /// /// </summary> /// <param name="request"></param> public void Test(Messages.Request request) { state = EndpointState.Listening; // All exceptions until a valid request was read // causes a message to be sent try { HandleRequest(request); } catch (Exception e) { SendException(e); } state = EndpointState.Idle; }
/// <summary> /// In any case, signals in main thread that an exit is requested /// Enters in ExitPending state and signals to the main worker /// that an exit is required /// </summary> public void Stop(string reason) { Log.Debug("Endpoint will exist because '{0}'", reason); if (state == EndpointState.Listening) { state = EndpointState.ExitPending; stopSignal.Set(); } else if (state == EndpointState.Idle) { Environment.Exit(0); } }
protected internal void _endpoint_state_cb(EndpointState msg, int kin_chain) { lock (this) { _last_endpoint_state = _stopwatch.ElapsedMilliseconds; /*if (!msg.valid) * { * _endpoint_pose = null; * _endpoint_vel = null; * return; * }*/ var p = new Pose(); p.orientation.w = msg.pose.orientation.w; p.orientation.x = msg.pose.orientation.x; p.orientation.y = msg.pose.orientation.y; p.orientation.z = msg.pose.orientation.z; p.position.x = msg.pose.position.x; p.position.y = msg.pose.position.y; p.position.z = msg.pose.position.z; var v = new SpatialVelocity(); v.angular.x = msg.twist.angular.x; v.angular.y = msg.twist.angular.y; v.angular.z = msg.twist.angular.z; v.linear.x = msg.twist.linear.x; v.linear.y = msg.twist.linear.y; v.linear.z = msg.twist.linear.z; if (_endpoint_pose == null) { if (_arm_selection == BaxterRobotArmSelection.both) { _endpoint_pose = new Pose[2]; } else { _endpoint_pose = new Pose[1]; } _endpoint_pose[kin_chain] = p; } if (_endpoint_vel == null) { _endpoint_vel = new SpatialVelocity[2]; _endpoint_vel[kin_chain] = v; } } }
public IOrEndpointStateBuilder Then( EndpointState endpointState, Action <IEndpointStateBuilder>?configure = null) { var builder = new EndpointStateBuilder(endpointState); configure?.Invoke(builder); if (_branches.TryAdd(endpointState, builder.Node) == false) { throw new ArgumentException( paramName: nameof(endpointState), message: $"{endpointState.GetType()} state have already been declared"); } return(this); }
/// <summary> /// Decrypts data according to the cipher settings. /// </summary> /// <param name="Data">Data to decrypt.</param> /// <param name="Header">Record header.</param> /// <param name="Start">Start offset of header.</param> /// <param name="State">Endpoint state.</param> /// <returns>Decrypted data, or null if authentication failed.</returns> public override byte[] Decrypt(byte[] Data, byte[] Header, int Start, EndpointState State) { lock (this.aesCcm) { // On AEAD ciphers, see RFC 5246, §6.2.3.3 int RecordIvLength = 12 - this.fixedIvLength; int N = Data.Length - RecordIvLength; byte[] CipherText = new byte[N]; byte[] Nonce = new byte[12]; byte[] AD = this.GetAssociatedData(Header, Start); byte[] PlainText; ushort Len; Len = AD[11]; Len <<= 8; Len |= AD[12]; Len -= (ushort)(this.t + RecordIvLength); AD[11] = (byte)(Len >> 8); AD[12] = (byte)Len; Array.Copy(Data, 0, Nonce, this.fixedIvLength, RecordIvLength); Array.Copy(Data, RecordIvLength, CipherText, 0, N); if (State.isClient) { Array.Copy(State.server_write_IV, 0, Nonce, 0, this.fixedIvLength); PlainText = this.aesCcm.AuthenticateAndDecrypt(CipherText, AD, Nonce, State.server_write_key); } else { Array.Copy(State.client_write_IV, 0, Nonce, 0, this.fixedIvLength); PlainText = this.aesCcm.AuthenticateAndDecrypt(CipherText, AD, Nonce, State.client_write_key); } return(PlainText); } }
/// <summary> /// Sets up everything and starts listenning for request /// </summary> /// <param name="type"></param> public void Listen(BrowserType type) { Setup(type); Log.Debug("Endpoint enter listenning mode for {0} ...", browserType); state = EndpointState.Listening; requestQueueWorker.Start(); responseQueueWorker.Start(); mainWorker.Start(); // All workers started, waiting here for stopSignal stopSignal.WaitOne(); Log.Debug("Endpoint exit listenning mode ..."); state = EndpointState.ExitPending; Teardown(); state = EndpointState.Idle; }
/// <summary> /// Finishes the handshake. /// </summary> /// <param name="Endpoint">Endpoint.</param> /// <param name="State">Endpoint state.</param> /// <param name="Resendable">If flight of records is resendable.</param> public virtual void SendFinished(DtlsEndpoint Endpoint, EndpointState State, bool Resendable) { if (State.masterSecret == null) { Endpoint.SendAlert(AlertLevel.fatal, AlertDescription.handshake_failure, State); } else { string Label; byte[] HandshakeHash; byte[] VerifyData; if (State.isClient) { State.clientFinished = true; Label = "client finished"; State.CalcClientHandshakeHash(); HandshakeHash = State.clientHandshakeHash; } else { State.serverFinished = true; Label = "server finished"; State.CalcServerHandshakeHash(); HandshakeHash = State.serverHandshakeHash; } VerifyData = this.PRF(State.masterSecret, Label, HandshakeHash, 12); Endpoint.SendHandshake(HandshakeType.finished, VerifyData, false, Resendable, State); if (State.clientFinished && State.serverFinished) { Endpoint.HandshakeSuccess(State); } } }
/// <summary> /// /// </summary> private void Teardown() { if (state != EndpointState.ExitPending) { throw new EndpointException("Call Endpoint::Teardown from an incompatible state : " + state.ToString()); } if (state == EndpointState.Teardown) { return; } Log.Debug("Endpoint Tearing down ..."); state = EndpointState.Teardown; stopSignal.Close(); stopSignal = null; try { if (mainWorker.IsAlive) { mainWorker.Abort(); } if (requestQueueWorker.IsAlive) { requestQueueWorker.Abort(); } if (responseQueueWorker.IsAlive) { responseQueueWorker.Abort(); } } finally { Environment.Exit(0); } }
private void ProcessInvMessage(EndpointState endpointState, InvMessage invMessage) { DateTime utcNow = SystemTime.UtcNow; GetDataMessage getDataMessage = null; lock (lockObject) { foreach (InventoryVector vector in invMessage.Inventory) { if (vector.Type == InventoryVectorType.MsgBlock) { endpointState.AdvertisedBlocks.Add(vector.Hash, utcNow); } } while (endpointState.AdvertisedBlocks.Count > MaxAdvertisedBlocksPerNode) { endpointState.AdvertisedBlocks.Remove(endpointState.AdvertisedBlocks.First().Key); } int maxBlocksToRequest = MaxConcurrentBlockRequestsPerNode - endpointState.BlockRequests.Count; List<BlockState> blocksToRequest = new List<BlockState>(); if (maxBlocksToRequest > 0) { foreach (BlockState blockState in requiredBlocks.Values) { if (blockState.GetPendingRequestCount() >= MaxConcurrentBlockRequestsPerBlock) { continue; } if (!endpointState.AdvertisedBlocks.ContainsKey(blockState.Hash)) { continue; } //todo: there are situations when request was sent, but timed out and should be requested again if (endpointState.HasPendingRequest(blockState.Hash)) { continue; } blocksToRequest.Add(blockState); if (blocksToRequest.Count >= maxBlocksToRequest) { break; } } } if (blocksToRequest.Any()) { InventoryVector[] inventoryVectors = blocksToRequest.Select(b => new InventoryVector(InventoryVectorType.MsgBlock, b.Hash)).ToArray(); getDataMessage = new GetDataMessage(inventoryVectors); foreach (BlockState blockState in blocksToRequest) { BlockRequest blockRequest = new BlockRequest(blockState, endpointState.Endpoint, utcNow); endpointState.BlockRequests.Add(blockState.Hash, blockRequest); blockState.Requests.Add(blockRequest); } } } if (getDataMessage != null) { endpointState.Endpoint.WriteMessage(getDataMessage); } }
public SSBIEndpoint(Endpoint ep) { _name = ep.Name; _state = ep.EndpointState; _isMsgFwd = ep.Payload.ServiceBroker.IsMessageForwardingEnabled; _fwdSize = ep.Payload.ServiceBroker.MessageForwardingSize; _auth = ep.Payload.ServiceBroker.EndpointAuthenticationOrder; _cert = ep.Payload.ServiceBroker.Certificate; _encrypt = ep.Payload.ServiceBroker.EndpointEncryption; _alg = ep.Payload.ServiceBroker.EndpointEncryptionAlgorithm; _port = ep.Protocol.Tcp.ListenerPort; _ep = ep; }