private void OnPKReport(ActionCompletedUnit ou) { _PkReportReceivedTimeStamp = DateTime.Now; if (_PKReportPKReport.Result.State == ActionStates.Completed && _PKReportPKReport.SpecificResult.Command != null && _PKReportPKReport.SpecificResult.Command.Length > 2) { COMMAND_CLASS_SECURITY_2.PUBLIC_KEY_REPORT rpt = _PKReportPKReport.SpecificResult.Command; if (rpt.properties1.includingNode == 1) { var receiverPublicKey = ((List <byte>)rpt.ecdhPublicKey).ToArray(); if (receiverPublicKey != null && receiverPublicKey.Length == 32 && ValidatePublicKeyReport(receiverPublicKey)) { var senderPublicKey = _securityManagerInfo.GetJoinPublicKeyS2(); if (_isClientSideAuthRequested && _KEX_SET.properties1.requestCsa > 0 && _securityManagerInfo.DSKVerificationOnReceiverCallback != null) { byte[] senderDSK = _securityManagerInfo.DSKVerificationOnReceiverCallback(); if (senderDSK != null && senderDSK.Length == 4) { Array.Copy(senderDSK, 0, receiverPublicKey, 0, 4); } } _securityManagerInfo.SetNetworkKeyS2Temp(_securityManagerInfo.CalculateTempNetworkKeyS2(receiverPublicKey, false)); _securityManagerInfo.ActivateNetworkKeyS2TempForNode(_peerNodeId); var kexSetEcho = _KEX_SET; kexSetEcho.properties1.echo = 1; _KEXSetEchoKEXReportEcho.DestNodeId = NodeId; _KEXSetEchoKEXReportEcho.SrcNodeId = VirtualNodeId; _KEXSetEchoKEXReportEcho.Data = kexSetEcho; _isWaitingForKexReportEcho = true; #region KEXSetEcho _securityTestSettingsService.ActivateTestPropertiesForFrame(SecurityS2TestFrames.KEXSetEcho, _KEXSetEchoKEXReportEcho); #endregion } else { _KexFail.Data = new COMMAND_CLASS_SECURITY_2.KEX_FAIL { kexFailType = 0x00 }; _KexFail.NodeId = NodeId; _KexFail.BridgeNodeId = VirtualNodeId; ou.SetNextActionItems(_KexFail); } } else { SetStateCompletedSecurityFailed(ou); } } else { SetStateCompletedSecurityFailed(ou); } }
private void OnKEXSet(ActionCompletedUnit ou) { if (_KEXReportKEXSet.Result && _KEXReportKEXSet.Result.State == ActionStates.Completed && _KEXReportKEXSet.SpecificResult.Command != null && _KEXReportKEXSet.SpecificResult.Command.Length > 2) { _grantedKeys.Clear(); _KEX_SET = _KEXReportKEXSet.SpecificResult.Command; if (_KEX_SET.properties1.echo == 0 && _KEX_SET.selectedKexScheme == 0x02 && _KEX_SET.selectedEcdhProfile == 0x01) { if (CheckIsCsaCorrectlyGranted() && ValidateKexSetKeys()) { bool hasHighKeys = false; NetworkKeyS2Flags grantedKeysMask = (NetworkKeyS2Flags)_KEX_SET.grantedKeys; if (grantedKeysMask.HasFlag(NetworkKeyS2Flags.S2Class2)) { _grantedKeys.Enqueue(NetworkKeyS2Flags.S2Class2); hasHighKeys = true; } if (grantedKeysMask.HasFlag(NetworkKeyS2Flags.S2Class1)) { _grantedKeys.Enqueue(NetworkKeyS2Flags.S2Class1); hasHighKeys = true; } if (grantedKeysMask.HasFlag(NetworkKeyS2Flags.S2Class0)) { _grantedKeys.Enqueue(NetworkKeyS2Flags.S2Class0); } if (grantedKeysMask.HasFlag(NetworkKeyS2Flags.S0)) { _grantedKeys.Enqueue(NetworkKeyS2Flags.S0); } _PKReportPKReport.DestNodeId = NodeId; _PKReportPKReport.SrcNodeId = VirtualNodeId; var cmd = new COMMAND_CLASS_SECURITY_2.PUBLIC_KEY_REPORT(); cmd.properties1 = 0; cmd.ecdhPublicKey = new List <byte>(_securityManagerInfo.GetJoinPublicKeyS2()); _isClientSideAuthGranted = _KEX_SET.properties1.requestCsa > 0 ? true : false; if (hasHighKeys && !_isClientSideAuthGranted && cmd.ecdhPublicKey.Count > 1) { cmd.ecdhPublicKey[0] = 0; cmd.ecdhPublicKey[1] = 0; if (_securityManagerInfo.DskPinCallback != null) { _securityManagerInfo.DskPinCallback(); } } _PKReportPKReport.Data = cmd; #region PublicKeyReportB _securityTestSettingsService.ActivateTestPropertiesForFrame(SecurityS2TestFrames.PublicKeyReportB, _PKReportPKReport); #endregion } else { _KexFail.Data = new COMMAND_CLASS_SECURITY_2.KEX_FAIL { kexFailType = 0x01 }; _KexFail.NodeId = NodeId; _KexFail.BridgeNodeId = VirtualNodeId; ou.SetNextActionItems(_KexFail); } } else { byte currentKexFailType = _KEX_SET.selectedKexScheme != 0x02 ? (byte)0x02 : (byte)0x00; if (currentKexFailType == 0x00) { currentKexFailType = _KEX_SET.selectedEcdhProfile != 0x01 ? (byte)0x03 : (byte)0x00; } _KexFail.Data = new COMMAND_CLASS_SECURITY_2.KEX_FAIL { kexFailType = currentKexFailType }; _KexFail.NodeId = NodeId; _KexFail.BridgeNodeId = VirtualNodeId; ou.SetNextActionItems(_KexFail); } } else { SetStateCompletedSecurityFailed(ou); } }