public EKEAlice(TheBallEKE ekeContext, bool isAsync = false) { EKEContext = ekeContext; AlicesActions = new NegotiationAction[] { Alice1_1_GenerateKeyPair, Alice1_2_EncryptPublicKeyWithS, Alice1_3_SendEncryptedPublicKeyToBob, Alice3_0_GetEncryptedSessionKeyFromBob, Alice3_1_DecryptSessionKey, Alice3_2_GenerateAliceRandomValue, Alice3_3_EncryptAliceRandomValueWithSessionKey, Alice3_4_SendEncryptedAliceRandomToBob, Alice5_0_GetAlicesRandomWithBobsRandomEncryptedFromBob, Alice5_1_DecryptBothRandoms, Alice5_2_VerifyAliceRandomInCombinedRandom, Alice5_3_ExtractBobsRandom, Alice5_4_EncryptBobsRandom, Alice5_5_SendEncryptedBobsRandomToBob, AliceX_DoneWithEKE }; AlicesActionsAsync = new NegotiationActionAsync[] { Alice1_1_GenerateKeyPairAsync, Alice1_2_EncryptPublicKeyWithSAsync, Alice1_3_SendEncryptedPublicKeyToBobAsync, Alice3_0_GetEncryptedSessionKeyFromBobAsync, Alice3_1_DecryptSessionKeyAsync, Alice3_2_GenerateAliceRandomValueAsync, Alice3_3_EncryptAliceRandomValueWithSessionKeyAsync, Alice3_4_SendEncryptedAliceRandomToBobAsync, Alice5_0_GetAlicesRandomWithBobsRandomEncryptedFromBobAsync, Alice5_1_DecryptBothRandomsAsync, Alice5_2_VerifyAliceRandomInCombinedRandomAsync, Alice5_3_ExtractBobsRandomAsync, Alice5_4_EncryptBobsRandomAsync, Alice5_5_SendEncryptedBobsRandomToBobAsync, AliceX_DoneWithEKEAsync }; CurrentActionIndex = 0; WaitForOtherParty = false; IsAsync = isAsync; }
public static void TestExecution() { TheBallEKE bobInstance = new TheBallEKE(); bobInstance.InitiateCurrentSymmetricFromSecret("testsecret2"); EKEBob bob = new EKEBob(ekeContext: bobInstance); TheBallEKE aliceInstance = new TheBallEKE(); aliceInstance.InitiateCurrentSymmetricFromSecret("testsecret2"); EKEAlice alice = new EKEAlice(ekeContext: aliceInstance); // Hook message senders alice.SendMessageToOtherParty = msg => { bob.LatestMessageFromOtherParty = msg; }; bob.SendMessageToOtherParty = msg => { alice.LatestMessageFromOtherParty = msg; }; bool ekeInProgress = true; while (ekeInProgress) { alice.PerformNextAction(); bob.PerformNextAction(); ekeInProgress = alice.IsDoneWithProtocol == false || bob.IsDoneWithProtocol == false; } bool ekeSuccess = true; }
public EKEBob(TheBallEKE ekeContext) { EKEContext = ekeContext; BobsActions = new NegotiationAction[] { Bob2_0_GetAlicesEncryptedPublicKeyFromAlice, Bob2_1_DecryptAlicesEncryptedPublicKey, Bob2_2_GenerateRandomSessionKeyWithIV, Bob2_3_EncryptSessionKey, Bob2_4_SendEncryptedSessionKeyToAlice, Bob4_0_GetAlicesRandomEncryptedFromAlice, Bob4_1_DecryptAlicesEncryptedRandom, Bob4_2_GenerateBobsRandomAndCombineWithAlicesRandom, Bob4_3_SendBothRandomsEncryptedToAlice, Bob6_0_GetBobsRandomEncryptedFromAlice, Bob6_1_DecryptBobsRandomFromAlice, Bob6_2_VerifyBobsRandom, BobX_DoneWithEKE }; }
public EKEAlice(TheBallEKE ekeContext) { EKEContext = ekeContext; AlicesActions = new NegotiationAction[] { Alice1_1_GenerateKeyPair, Alice1_2_EncryptPublicKeyWithS, Alice1_3_SendEncryptedPublicKeyToBob, Alice3_0_GetEncryptedSessionKeyFromBob, Alice3_1_DecryptSessionKey, Alice3_2_GenerateAliceRandomValue, Alice3_3_EncryptAliceRandomValueWithSessionKey, Alice3_4_SendEncryptedAliceRandomToBob, Alice5_0_GetAlicesRandomWithBobsRandomEncryptedFromBob, Alice5_1_DecryptBothRandoms, Alice5_2_VerifyAliceRandomInCombinedRandom, Alice5_3_ExtractBobsRandom, Alice5_4_EncryptBobsRandom, Alice5_5_SendEncryptedBobsRandomToBob, AliceX_DoneWithEKE }; }
public EKEBob(TheBallEKE ekeContext, bool isAsync = false) { EKEAlice al; EKEContext = ekeContext; BobsActions = new NegotiationAction[] { Bob2_0_GetAlicesEncryptedPublicKeyFromAlice, Bob2_1_DecryptAlicesEncryptedPublicKey, Bob2_2_GenerateRandomSessionKeyWithIV, Bob2_3_EncryptSessionKey, Bob2_4_SendEncryptedSessionKeyToAlice, Bob4_0_GetAlicesRandomEncryptedFromAlice, Bob4_1_DecryptAlicesEncryptedRandom, Bob4_2_GenerateBobsRandomAndCombineWithAlicesRandom, Bob4_3_SendBothRandomsEncryptedToAlice, Bob6_0_GetBobsRandomEncryptedFromAlice, Bob6_1_DecryptBobsRandomFromAlice, Bob6_2_VerifyBobsRandom, BobX_DoneWithEKE }; BobsActionsAsync = new NegotiationActionAsync[] { Bob2_0_GetAlicesEncryptedPublicKeyFromAliceAsync, Bob2_1_DecryptAlicesEncryptedPublicKeyAsync, Bob2_2_GenerateRandomSessionKeyWithIVAsync, Bob2_3_EncryptSessionKeyAsync, Bob2_4_SendEncryptedSessionKeyToAliceAsync, Bob4_0_GetAlicesRandomEncryptedFromAliceAsync, Bob4_1_DecryptAlicesEncryptedRandomAsync, Bob4_2_GenerateBobsRandomAndCombineWithAlicesRandomAsync, Bob4_3_SendBothRandomsEncryptedToAliceAsync, Bob6_0_GetBobsRandomEncryptedFromAliceAsync, Bob6_1_DecryptBobsRandomFromAliceAsync, Bob6_2_VerifyBobsRandomAsync, BobX_DoneWithEKEAsync }; CurrentActionIndex = 0; WaitForOtherParty = true; IsAsync = isAsync; }
public static void EchoClient() { Console.WriteLine("Starting EKE WSS connection"); //string hostWithProtocolAndPort = "ws://*****:*****@gmail.com"; string idParam = "groupID=4ddf4bef-0f60-41b6-925d-02721e89d637"; string deviceConnectionUrl = hostWithProtocolAndPort + "/websocket/NegotiateDeviceConnection?" + idParam; //socket = new WebSocket("wss://theball.protonit.net/websocket/mytest.k"); socket = new WebSocket(deviceConnectionUrl); socket.OnOpen += socket_OnOpen; socket.OnClose += socket_OnClose; socket.OnError += socket_OnError; socket.OnMessage += socket_OnMessage; TheBallEKE instance = new TheBallEKE(); instance.InitiateCurrentSymmetricFromSecret("testsecretXYZ33"); playAlice = false; if (playAlice) { protocolMember = new TheBallEKE.EKEAlice(instance); } else { protocolMember = new TheBallEKE.EKEBob(instance); } protocolMember.SendMessageToOtherParty = bytes => { socket.Send(bytes); }; watch.Start(); socket.Connect(); #if native45 //WebSocket socket = new ClientWebSocket(); //WebSocket.CreateClientWebSocket() ClientWebSocket socket = new ClientWebSocket(); Uri uri = new Uri("ws://localhost:50430/websocket/mytest.k"); var cts = new CancellationTokenSource(); await socket.ConnectAsync(uri, cts.Token); Console.WriteLine(socket.State); Task.Factory.StartNew( async() => { var rcvBytes = new byte[128]; var rcvBuffer = new ArraySegment <byte>(rcvBytes); while (true) { WebSocketReceiveResult rcvResult = await socket.ReceiveAsync(rcvBuffer, cts.Token); byte[] msgBytes = rcvBuffer.Skip(rcvBuffer.Offset).Take(rcvResult.Count).ToArray(); string rcvMsg = Encoding.UTF8.GetString(msgBytes); Console.WriteLine("Received: {0}", rcvMsg); } }, cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default); while (true) { var message = Console.ReadLine(); if (message == "Bye") { cts.Cancel(); return; } byte[] sendBytes = Encoding.UTF8.GetBytes(message); var sendBuffer = new ArraySegment <byte>(sendBytes); await socket.SendAsync(sendBuffer, WebSocketMessageType.Text, endOfMessage : true, cancellationToken : cts.Token); } #endif }
private async static Task HandleDeviceNegotiations(InformationContext iCtx, WebSocketContext wsCtx, WebSocket socket, byte[] binaryMessage, string textMessage) { if(iCtx != InformationContext.Current) throw new InvalidDataException("InformationContext is mismatched during processing"); bool playBob = false; INegotiationProtocolMember protocolParty = null; if (binaryMessage != null) { iCtx.AccessLockedItems(dict => { if (dict.ContainsKey("EKENEGOTIATIONPARTY") == false) { // Yes, the shared secret is fixed due to demo. We're fixing it to be separately requested or given by user... :-) TheBallEKE protocolInstance = new TheBallEKE(); var decryptedSharedSecretPayload = EncryptionSupport.DecryptData(binaryMessage); var nonse = decryptedSharedSecretPayload.Take(32).ToArray(); var secret = decryptedSharedSecretPayload.Skip(32).Take(32).ToArray(); long ticks = BitConverter.ToInt64(decryptedSharedSecretPayload, 64); DateTime validUntilUtc = new DateTime(ticks, DateTimeKind.Utc); if(DateTime.UtcNow > validUntilUtc) throw new SecurityException("Shared secret payload is expired"); protocolInstance.InitiateCurrentSymmetricFromSecret(secret); if(playBob) protocolParty = new TheBallEKE.EKEBob(protocolInstance, true); else protocolParty = new TheBallEKE.EKEAlice(protocolInstance, true); dict.Add("EKENEGOTIATIONPARTY", protocolParty); } else { protocolParty = (INegotiationProtocolMember)dict["EKENEGOTIATIONPARTY"]; } }); if (protocolParty.SendMessageToOtherPartyAsync == null) { protocolParty.SendMessageToOtherPartyAsync = async bytes => { await SendBinaryMessage(socket, bytes); }; if(playBob) // if we play bob we put the current message already to the pipeline protocolParty.LatestMessageFromOtherParty = binaryMessage; } else { // Alice plays first, so only after the second message we start putting messages from Bob protocolParty.LatestMessageFromOtherParty = binaryMessage; } while (protocolParty.IsDoneWithProtocol == false && protocolParty.WaitForOtherParty == false) { await protocolParty.PerformNextActionAsync(); } } else { iCtx.AccessLockedItems(dict => { if (dict.ContainsKey("EKENEGOTIATIONPARTY")) protocolParty = (INegotiationProtocolMember) dict["EKENEGOTIATIONPARTY"]; }); if (protocolParty != null && protocolParty.IsDoneWithProtocol) // Perform POST EKE operations { iCtx.AccessLockedItems(dict => dict.Remove("EKENEGOTIATIONPARTY")); string deviceID = FinishDeviceNegotiation(iCtx, protocolParty, textMessage); await SendTextMessage(socket, deviceID); } //await SendTextMessage(socket, echoString); } }
public static void TestExecution() { TheBallEKE instance = new TheBallEKE(); instance.InitiateCurrentSymmetricFromSecret("testsecret"); EKEAlice alice = new EKEAlice(ekeContext: instance); EKEBob bob = new EKEBob(ekeContext: instance); // Hook message senders alice.SendMessageToBob = msg => { bob.LatestMessageFromAlice = msg; bob.WaitForAlice = false; }; bob.SendMessageToAlice = msg => { alice.LatestMessageFromBob = msg; alice.WaitForBob = false; }; bool ekeInProgress = true; int aliceActionIX = 0; int bobActionIX = 0; while (ekeInProgress) { bool alicesTurn = alice.IsDoneWithEKE == false && alice.WaitForBob == false; bool bobsTurn = !alicesTurn; if (alicesTurn) { do { alice.AlicesActions[aliceActionIX++](); } while (alice.IsDoneWithEKE == false && alice.WaitForBob == false); } else { do { bob.BobsActions[bobActionIX++](); } while (bob.IsDoneWithEKE == false && bob.WaitForAlice == false); } ekeInProgress = alice.IsDoneWithEKE == false || bob.IsDoneWithEKE == false; } bool ekeSuccess = true; #if never instance.Alice1_1_GenerateKeyPair(); instance.Alice1_2_EncryptPublicKeyWithS(); instance.Alice1_3_SendEncryptedPublicKeyToBob(msgToBob => { instance.Bob.AlicesEncryptedPublicKey = msgToBob; }); instance.Bob2_1_DecryptAlicesEncryptedPublicKey(); instance.Bob2_2_GenerateRandomSessionKeyWithIV(); instance.Bob2_3_EncryptSessionKey(); instance.Bob2_4_SendEncryptedSessionKeyToAlice(msgToAlice => { instance.Alice.EncryptedSessionKey = msgToAlice; }); instance.Alice3_1_DecryptSessionKey(); instance.Alice3_2_GenerateAliceRandomValue(); instance.Alice3_3_EncryptAliceRandomValueWithSessionKey(); instance.Alice3_4_SendEncryptedAliceRandomToBob(msgToBob => { instance.Bob.AlicesEncryptedRandom = msgToBob; }); instance.Bob4_1_DecryptAlicesEncryptedRandom(); instance.Bob4_2_GenerateBobsRandomAndCombineWithAlicesRandom(); instance.Bob4_3_SendBothRandomsEncryptedToAlice(msgToAlice => { instance.Alice.AlicesRandomWithBobsRandomEncrypted = msgToAlice; }); instance.Alice5_1_DecryptBothRandoms(); instance.Alice5_2_VerifyAliceRandomInCombinedRandom(); instance.Alice5_3_ExtractBobsRandom(); instance.Alice5_4_EncryptBobsRandom(); instance.Alice5_5_SendEncryptedBobsRandomToBob(msgToBob => { instance.Bob.BobsRandomFromAliceEncrypted = msgToBob; }); instance.Bob6_1_DecryptBobsRandomFromAlice(); instance.Bob6_2_VerifyBobsRandom(); #endif }
private static SecurityNegotiationManager InitSecurityNegotiationManager(string deviceConnectionUrl, byte[] sharedSecret, string deviceDescription, bool playAsAlice) { SecurityNegotiationManager securityNegotiationManager = new SecurityNegotiationManager(); securityNegotiationManager.Socket = new WebSocket(deviceConnectionUrl); securityNegotiationManager.Socket.OnOpen += securityNegotiationManager.socket_OnOpen; securityNegotiationManager.Socket.OnClose += securityNegotiationManager.socket_OnClose; securityNegotiationManager.Socket.OnError += securityNegotiationManager.socket_OnError; securityNegotiationManager.Socket.OnMessage += securityNegotiationManager.socket_OnMessage; TheBallEKE instance = new TheBallEKE(); instance.InitiateCurrentSymmetricFromSecret(sharedSecret); securityNegotiationManager.PlayAsAlice = playAsAlice; securityNegotiationManager.DeviceDescription = deviceDescription; if (securityNegotiationManager.PlayAsAlice) { securityNegotiationManager.ProtocolMember = new TheBallEKE.EKEAlice(instance); } else { securityNegotiationManager.ProtocolMember = new TheBallEKE.EKEBob(instance); } securityNegotiationManager.ProtocolMember.SendMessageToOtherParty = bytes => { securityNegotiationManager.Socket.Send(bytes); }; return securityNegotiationManager; }