示例#1
0
		/// <summary>
		/// Generate a handshake packet for the current keys
		/// </summary>
		public Packet Handshake(byte csid, bool isReply = false)
		{
			Packet inner = new Packet ();
			Packet keyPacket = new Packet ();
			foreach (var csItem in Local.CipherSets) {
				if (csItem.Value.CSID == csid) {
					keyPacket.Body = csItem.Value.Keys.PublicKey;
				} else {
					keyPacket.Head.Add (csItem.Value.CSID.ToString (), Base32Encoder.Encode (csItem.Value.Keys.PublicKey));
				}
			}
			if (isReply) {
				inner.Head.Add ("at", OutAt);
			} else {
				inner.Head.Add ("at", NextAt());
			}
			inner.Head.Add ("csid", csid.ToString ("x2"));
			keyPacket.Encode ();
			inner.Body = keyPacket.FullPacket;
			inner.Encode ();

			Packet outer = Local.CipherSets[csid].MessageEncrypt(remoteInfo, inner);
			outer.HeadBytes = new byte[1];
			outer.HeadLength = 1;
			outer.HeadBytes [0] = csid;
			outer.Encode ();

			return outer;
		}
示例#2
0
		public static Packet DecodePacket(byte[] packetData)
		{
			Packet pkt = new Packet();
			if (!pkt.Decode(packetData)) {
				return null;
			}
			return pkt;
		}
示例#3
0
		/// <summary>
		/// Attempt to Decrypt a packet sent to us.
		/// </summary>
		/// <param name="outer">A packet to attempt to decrypt</param>
		public Packet Decrypt(Packet outer) 
		{
			ICipherSet cs;
			if (CipherSets.TryGetValue (outer.HeadBytes [0], out cs)) {
				return cs.MessageDecrypt (outer);
			}

			return null;
		}
示例#4
0
		public Packet MessageEncrypt(ICipherSetRemoteInfo remoteInfo, Packet inner)
		{
			CS1ARemoteInfo ri = (CS1ARemoteInfo)remoteInfo;

			var agreedValue = ECDHAgree (ri.RemotePublicKey, ri.EphemeralKeys.PrivateKey);

			// Hash the agreed key
			var hashedValue = Helpers.SHA256Hash (Helpers.ToByteArray(agreedValue, 20));

			// Fold to get the actual key for AES
			byte[] aesKey = Helpers.Fold (hashedValue);
			Random rnd = new Random ();

			// Setup and encrypt the actual data
			byte[] aesIV = new byte[16];
			rnd.NextBytes (aesIV);
			Array.Clear (aesIV, 4, 12);

			var cipher = new SicBlockCipher (new AesFastEngine ());
			var parameters = new ParametersWithIV (new KeyParameter (aesKey), aesIV);
			cipher.Init (true, parameters);

			var encryptedInner = new byte[inner.FullPacket.Length];
			BufferedBlockCipher bufferCipher = new BufferedBlockCipher (cipher);
			var offset = bufferCipher.ProcessBytes (inner.FullPacket, encryptedInner, 0);
			bufferCipher.DoFinal (encryptedInner, offset);

			// Construct the packet minus the hmac
			Packet outPacket = new Packet ();
			outPacket.Body = new byte[29 + encryptedInner.Length];
			Buffer.BlockCopy (ri.EphemeralKeys.PublicKey, 0, outPacket.Body, 0, ri.EphemeralKeys.PublicKey.Length);
			Buffer.BlockCopy (aesIV, 0, outPacket.Body, 21, 4);
			Buffer.BlockCopy (encryptedInner, 0, outPacket.Body, 25, encryptedInner.Length);

			// ECDH for the hmac key using 
			var idAgreedValue = ECDHAgree (ri.RemotePublicKey, Key.PrivateKey);

			// Mash on the IV for the compound key
			byte[] macKey = new byte[24];
			byte[] idAgreedValueArray = Helpers.ToByteArray(idAgreedValue, 20);
			Buffer.BlockCopy(idAgreedValueArray, 0, macKey, 0, idAgreedValueArray.Length);
			Buffer.BlockCopy(aesIV, 0, macKey, idAgreedValueArray.Length, 4);

			// Actually hmac all the data now
			var hmac = new HMac (new Sha256Digest ());
			hmac.Init(new KeyParameter (macKey, 0, 24));
			hmac.BlockUpdate(outPacket.Body, 0, 25 + encryptedInner.Length);
			byte[] mac = new byte[hmac.GetMacSize()];
			hmac.DoFinal(mac, 0);

			// Fold it up, shove it in and we're done
			var foldedMac = Helpers.Fold(mac, 3);
			Buffer.BlockCopy(foldedMac, 0, outPacket.Body, 25 + encryptedInner.Length, foldedMac.Length);

			return outPacket;
		}
示例#5
0
		public bool Handshake(Packet outer)
		{
			var linkData = Packet.DecodePacket (outer.Body);
			if (Exchange == null) {
				Exchange = new Exchange (Mesh.Self, 0x1a, linkData.Body);
				Exchange.OutAt = (uint)outer.Head ["at"];

				var tokenData = outer.Parent.Body.Take (16).ToArray ();
				var tokenHash = Helpers.SHA256Hash (tokenData).Take (16).ToArray ();
				Token = Helpers.ToHexSring (tokenHash);
			}
			if (!Exchange.Verify (outer.Parent)) {
				return false;
			}
			Exchange.Sync (outer);

			return true;
		}
示例#6
0
		public void Packet()
		{
			// Basic packet decoding
			byte[] packetData = StringToByteArray ("001d7b2274797065223a2274657374222c22666f6f223a5b22626172225d7d616e792062696e61727921");
			Telehash.E3X.Packet p = new Telehash.E3X.Packet (packetData);
			Assert.AreEqual (p.HeadLength, 29);
			Assert.AreEqual (p.Body.Length, 11);
			Assert.AreEqual ((string)p.Head ["type"], "test");
			Assert.AreEqual ((string)p.Head ["foo"] [0], "bar");

			Telehash.E3X.Packet encodeTestPacket = new Telehash.E3X.Packet ();
			encodeTestPacket.Body = p.Body;
			encodeTestPacket.Head.Add ("type", "test");
			var fooArray = new JArray ();
			fooArray.Add ("bar");
			encodeTestPacket.Head.Add ("foo", fooArray);
			encodeTestPacket.Encode ();
			Assert.AreEqual (packetData, encodeTestPacket.FullPacket);
		}
示例#7
0
        public void Packet()
        {
            // Basic packet decoding
            byte[] packetData     = StringToByteArray("001d7b2274797065223a2274657374222c22666f6f223a5b22626172225d7d616e792062696e61727921");
            Telehash.E3X.Packet p = new Telehash.E3X.Packet(packetData);
            Assert.AreEqual(p.HeadLength, 29);
            Assert.AreEqual(p.Body.Length, 11);
            Assert.AreEqual((string)p.Head ["type"], "test");
            Assert.AreEqual((string)p.Head ["foo"] [0], "bar");

            Telehash.E3X.Packet encodeTestPacket = new Telehash.E3X.Packet();
            encodeTestPacket.Body = p.Body;
            encodeTestPacket.Head.Add("type", "test");
            var fooArray = new JArray();

            fooArray.Add("bar");
            encodeTestPacket.Head.Add("foo", fooArray);
            encodeTestPacket.Encode();
            Assert.AreEqual(packetData, encodeTestPacket.FullPacket);
        }
示例#8
0
		public void Prepare(ICipherSetRemoteInfo info, Packet outer)
		{
			var ri = (CS1ARemoteInfo)info;

			ri.RemoteEphemeralKey = new byte[21];
			Buffer.BlockCopy (outer.Parent.Body, 0, ri.RemoteEphemeralKey, 0, 21);

			var secret = Helpers.ToByteArray(ECDHAgree (ri.RemoteEphemeralKey, ri.EphemeralKeys.PrivateKey), 20);
			var shaBuffer = new byte[secret.Length + ri.RemoteEphemeralKey.Length + ri.EphemeralKeys.PublicKey.Length];

			Buffer.BlockCopy (secret, 0, shaBuffer, 0, secret.Length);
			Buffer.BlockCopy (ri.RemoteEphemeralKey, 0, shaBuffer, secret.Length, ri.RemoteEphemeralKey.Length);
			Buffer.BlockCopy (ri.EphemeralKeys.PublicKey, 0, shaBuffer, secret.Length + ri.RemoteEphemeralKey.Length, ri.EphemeralKeys.PublicKey.Length);
			ri.DecryptionKey = Helpers.FoldOnce (Helpers.SHA256Hash (shaBuffer));

			Buffer.BlockCopy (ri.EphemeralKeys.PublicKey, 0, shaBuffer, secret.Length, ri.EphemeralKeys.PublicKey.Length);
			Buffer.BlockCopy (ri.RemoteEphemeralKey, 0, shaBuffer, secret.Length + ri.EphemeralKeys.PublicKey.Length, ri.RemoteEphemeralKey.Length);
			ri.EncryptionKey = Helpers.FoldOnce (Helpers.SHA256Hash (shaBuffer));

			var rnd = new SecureRandom ();
			ri.IV = (uint)rnd.NextInt ();

		}
示例#9
0
		public Packet ChannelDecrypt(ICipherSetRemoteInfo channelInfo, Packet outer)
		{
			// We gotta have the primary components and something to decrypt
			if (outer.Body.Length < 25) {
				return null;
			}

			var ci = (CS1ARemoteInfo)channelInfo;

			// Rip apart our packet
			byte[] token = outer.Body.Take (16).ToArray ();
			byte[] iv = outer.Body.Skip (16).Take (4).ToArray ();
			byte[] encryptedData = outer.Body.Skip (20).Take (outer.Body.Length - 24).ToArray ();
			byte[] dataMac = outer.Body.Skip (outer.Body.Length - 4).Take (4).ToArray ();

			// Make sure we're on the right channel
			if (!token.SequenceEqual (ci.Token)) {
				return null;
			}

			// Validate us some hmac
			byte[] hmacKey = new byte[20];
			Buffer.BlockCopy (ci.DecryptionKey, 0, hmacKey, 0, 16);
			Buffer.BlockCopy (iv, 0, hmacKey, 16, 4);

			var hmac = new HMac (new Sha256Digest ());
			hmac.Init(new KeyParameter (hmacKey));
			hmac.BlockUpdate(encryptedData, 0, encryptedData.Length);
			byte[] mac = new byte[hmac.GetMacSize()];
			hmac.DoFinal(mac, 0);
			var foldedMac = Helpers.Fold (mac, 3);

			if (!foldedMac.SequenceEqual (dataMac)) {
				// Get out of here with your bad data
				return null;
			}

			// Everything seems ok.  Get it decrypted
			byte[] aesIV = new byte[16];
			Buffer.BlockCopy (iv, 0, aesIV, 0, 4);
			Array.Clear (aesIV, 4, 12);

			var cipher = new SicBlockCipher (new AesFastEngine ());
			var parameters = new ParametersWithIV (new KeyParameter (ci.DecryptionKey), aesIV);
			cipher.Init (false, parameters);

			var decryptedData = new byte[encryptedData.Length];
			BufferedBlockCipher bufferCipher = new BufferedBlockCipher (cipher);
			var offset = bufferCipher.ProcessBytes (encryptedData, decryptedData, 0);
			bufferCipher.DoFinal (decryptedData, offset);

			// Build a packet and ship it off
			return Packet.DecodePacket (decryptedData);
		}
示例#10
0
		public Packet ChannelEncrypt(ICipherSetRemoteInfo channelInfo, Packet inner)
		{
			var ci = (CS1ARemoteInfo)channelInfo;

			// TODO:  Validate we don't care about endianess of IV here

			// Setup and encrypt the actual data
			byte[] aesIV = new byte[16];
			Buffer.BlockCopy (BitConverter.GetBytes(ci.IV), 0, aesIV, 0, 4);
			Array.Clear (aesIV, 4, 12);

			var cipher = new SicBlockCipher (new AesFastEngine ());
			var parameters = new ParametersWithIV (new KeyParameter (ci.EncryptionKey), aesIV);
			cipher.Init (true, parameters);

			var encryptedInner = new byte[inner.FullPacket.Length];
			BufferedBlockCipher bufferCipher = new BufferedBlockCipher (cipher);
			var offset = bufferCipher.ProcessBytes (inner.FullPacket, encryptedInner, 0);
			bufferCipher.DoFinal (encryptedInner, offset);

			// Hmac the output
			byte[] hmacKey = new byte[20];
			Buffer.BlockCopy (ci.EncryptionKey, 0, hmacKey, 0, 16);
			Buffer.BlockCopy (BitConverter.GetBytes(ci.IV), 0, hmacKey, 16, 4);

			var hmac = new HMac (new Sha256Digest ());
			hmac.Init(new KeyParameter (hmacKey));
			hmac.BlockUpdate(encryptedInner, 0, encryptedInner.Length);
			byte[] mac = new byte[hmac.GetMacSize()];
			hmac.DoFinal(mac, 0);
			var foldedMac = Helpers.Fold (mac, 3);

			// Create the outgoing packet
			Packet outPacket = new Packet();
			outPacket.Body = new byte[encryptedInner.Length + 24];
			Buffer.BlockCopy(ci.Token, 0, outPacket.Body, 0, 16);
			Buffer.BlockCopy(BitConverter.GetBytes(ci.IV), 0, outPacket.Body, 16, 4);
			Buffer.BlockCopy(encryptedInner, 0, outPacket.Body, 20, encryptedInner.Length);
			Buffer.BlockCopy(foldedMac, 0, outPacket.Body, outPacket.Body.Length - 4, 4);

			// Next IV next packet
			++ci.IV;

			return outPacket;
		}
示例#11
0
		public bool MessageVerify (ICipherSetRemoteInfo remoteInfo, Packet outer)
		{
			CS1ARemoteInfo ri = (CS1ARemoteInfo)remoteInfo;
			byte[] ivData = outer.Body.Skip(21).Take(4).ToArray();
			byte[] hmacData = outer.Body.Skip(outer.Body.Length - 4).Take(4).ToArray();

			// Check the hmac to validate the packet
			var agreedHMacKeyData = Helpers.ToByteArray (ECDHAgree (ri.RemotePublicKey, Key.PrivateKey), 20);
			byte[] hmacKey = new byte[24];
			if (agreedHMacKeyData.Length != 20) {
				// It's not a correct agreed value, expected 20 bytes
				return false;
			}
			Buffer.BlockCopy (agreedHMacKeyData, 0, hmacKey, 0, 20);
			Buffer.BlockCopy (ivData, 0, hmacKey, 20, 4);

			var hmac = new HMac (new Sha256Digest ());
			byte[] fullIv = new byte[16];
			Array.Clear (fullIv, 0, 16);
			Buffer.BlockCopy (ivData, 0, fullIv, 0, 4);
			hmac.Init(new KeyParameter (hmacKey, 0, 24));
			hmac.BlockUpdate(outer.Body, 0, outer.Body.Length - 4);
			byte[] mac = new byte[hmac.GetMacSize()];
			hmac.DoFinal(mac, 0);
			var macValue = Helpers.Fold (mac, 3);

			if (!macValue.SequenceEqual (hmacData)) {
				// The hmacs did not match, blow up the world
				return false;
			}

			return true;
		}
示例#12
0
		public void Encrypt(Packet msg)
		{
		}
示例#13
0
		public void Receive(Pipe pipe, Packet packet)
		{
			if (pipe == null || packet == null || packet.FullPacket.Length == 0) {
				DebugLog ("Invalid data sent to Receive");
				return;
			}

			DebugLog ("Received a packet: " + packet.ToDebugString());
			DebugLog ("Head length: " + packet.HeadLength + "\n");

			// Process handshakes
			if (packet.HeadLength == 1) {
				DebugLog ("Processing a handshake");

				var inner = self.Decrypt (packet);
				if (inner == null) {
					DebugLog ("There was no inner packet\n");
					return;
				}
				inner.Parent = packet;
				DebugLog ("Decrypted");
				DebugLog (inner.ToDebugString ());

				DebugLog ("HERE");

				JToken msgType;
				bool gotValue = inner.Head.TryGetValue ("type", out msgType);

				// TODO:  Handle other types correctly
				if (gotValue && msgType.ToString () != "link") {
					DebugLog ("We can only handle key type messages right now\n");
					return;
				}

				DebugLog ("Building hashname");
				// Get the hashname from the inner packet
				var keyPacket = Packet.DecodePacket (inner.Body);
				if (keyPacket == null) {
					DebugLog ("No key packet was in the handshake");
					return;
				}
				var hashKeys = new Dictionary<string, string> ();
				foreach (var entry in keyPacket.Head) {
					// TODO:  Move to the new inner packet syntax
					hashKeys.Add (entry.Key, entry.Value.ToString ());
				}
				var fromHashname = Telehash.Hashname.FromKey ("1a", keyPacket.Body, hashKeys);
				DebugLog ("Incoming hashname: " + fromHashname);

				Link curLink;
				if (Links.TryGetValue (fromHashname, out curLink)) {
					// TODO:  Replace an existing link
					JToken atToken;
					if (!inner.Head.TryGetValue ("at", out atToken)) {
						DebugLog ("No at value was found on handshake");
						return;
					}
					if (curLink.Exchange.At == atToken.Value<uint> ()) {
						if (!curLink.Handshake (inner)) {
							DebugLog ("Could not finish handshake");
							return;
						}
						if (LinkUp != null) {
							LinkUp (curLink);
						}
						DebugLog ("Start using channels?");
					}
					return;
				} else {
					// TODO:  Method to approve or reject the hashname?

					Link newLink = new Link (fromHashname);
					newLink.Mesh = this;
					if (!newLink.Handshake (inner)) {
						DebugLog ("Invalid Handshake for Link");
						return;
					}
					newLink.AddPipe (pipe);

					// We index both the hashname and the Token for different lookup cases
					Links.Add (fromHashname, newLink);
					DebugLog ("Token for new Link is " + Helpers.ToHexSring(newLink.Exchange.Token));
					Links.Add (Helpers.ToHexSring(newLink.Exchange.Token), newLink);

					if (LinkUp != null) {
						LinkUp (newLink);
					}
				}
			} else if (packet.HeadLength == 0) {

				byte[] token = packet.Body.Take(16).ToArray();
				Link link;
				if (Links.TryGetValue (Helpers.ToHexSring (token), out link)) {
					var outer = link.Exchange.Receive (packet);
					if (outer == null) {
						DebugLog ("Unable to decrypt a packet");
						// TODO:  Do we shutdown the link or exchange?  Probably not, DoS
					}
					DebugLog ("We got a channel packet: " + outer.ToDebugString ());
					link.Receive (outer, pipe);
				} else {
					DebugLog ("No known link for channel packet token: " + Helpers.ToHexSring (token));
					return;
				}
			}

			DebugLog ("We're out\n");
		}
示例#14
0
		public Packet Receive(Packet packet)
		{
			return cipherSet.ChannelDecrypt(remoteInfo, packet);
		}
示例#15
0
		public void Sync(Packet handshake)
		{
			cipherSet.Prepare (remoteInfo, handshake);
		}
示例#16
0
		public void Receive(Packet packet, Pipe pipe)
		{

		}
示例#17
0
		public void Send (Packet packet)
		{
			var sendData = packet.Cloak ();
			Client.Send (sendData, sendData.Length, remoteEndpoint);
		}
示例#18
0
		public Packet MessageDecrypt(Packet outer)
		{
			byte[] remoteKeyData = outer.Body.Take(21).ToArray();
			byte[] ivData = outer.Body.Skip(21).Take(4).ToArray();
			byte[] innerEncryptedData = outer.Body.Skip(25).Take(outer.Body.Length - 29).ToArray();

			// Decode the body
			ECKeyPair remoteEphemeralKeys = ECKeyPair.LoadKeys (SecNamedCurves.GetByName ("secp160r1"), remoteKeyData, null);

			var idAgreement = ECDHAgree (remoteEphemeralKeys.PublicKey, Key.PrivateKey);
			var agreedHash = Helpers.SHA256Hash (Helpers.ToByteArray (idAgreement, 20));
			var aesKey = Helpers.FoldOnce(agreedHash);

			// Pad out the IV
			byte[] aesIV = new byte[16];
			Array.Clear (aesIV, 0, 16);
			Buffer.BlockCopy (ivData, 0, aesIV, 0, 4);

			// Decrypt it
			var cipher = new BufferedBlockCipher (new SicBlockCipher (new AesFastEngine ()));
			var parameters = new ParametersWithIV (new KeyParameter (aesKey), aesIV);
			cipher.Init (false, parameters);
			byte[] decryptedBody = new byte[innerEncryptedData.Length];
			var offset = cipher.ProcessBytes (innerEncryptedData, decryptedBody, 0);
			cipher.DoFinal (decryptedBody, offset);

			Packet outPacket = Packet.DecodePacket (decryptedBody);

			return outPacket;
		}
示例#19
0
		public bool Verify(Packet msg)
		{
			return cipherSet.MessageVerify (remoteInfo, msg);
		}