Beispiel #1
0
        public static Meta GetSecure(Socket client, Stream toWriteTo, byte[] encryptionKey)
        {
            Meta meta = GetMeta(client);

            AesGcm gcm = new AesGcm(encryptionKey);

            byte[] buffer          = new byte[FileBufferSize + TagBufferSize];
            int    clientGetBuffer = client.SendBufferSize;

            client.ReceiveBufferSize = FileBufferSize + TagBufferSize;

            BigInteger count = 0;

            for (BigInteger i = 0; meta.Size != count; i++)
            {
                int bytes = client.Receive(buffer, buffer.Length, SocketFlags.None);
                count += bytes - TagBufferSize;

                byte[] cypher = subArray(buffer, 0, bytes - TagBufferSize);
                byte[] tag    = subArray(buffer, bytes - TagBufferSize, bytes);

                byte[] nonce = Base255.ToByteArr(i, NonceBufferSize);

                byte[] plainText = new byte[cypher.Length];
                gcm.Decrypt(nonce, cypher, tag, plainText);

                toWriteTo.Write(plainText, 0, plainText.Length);
            }
            client.ReceiveBufferSize = clientGetBuffer;
            return(meta);
        }
Beispiel #2
0
        /// <summary>
        /// Gets meta file structure from client.
        /// Abstain from using this method, unless you know how it works.
        /// <para/>
        /// See <see cref="Transfer.Send(Socket, Meta, System.IO.Stream)"/>,
        /// or see <see cref="Transfer.SendFile(Socket, string)"/>
        /// </summary>
        /// <exception cref="System.Exception">
        /// Thrown when the promised bytes and received bytes don't match.
        /// </exception>
        /// <exception cref="System.Net.Sockets.SocketException">
        /// Thrown when a receive operation has failed, the client has disconnected.
        /// </exception>

        public static Meta GetMeta(Socket client)
        {
            // Get
            byte[] metaBuffer = new byte[MetaBufferSize];

            int clientBufferSize = client.ReceiveBufferSize;

            client.ReceiveBufferSize = metaBuffer.Length;

            int bytes = client.Receive(metaBuffer);

            // Probably disconnected.
            if (bytes == 0)
            {
                throw new SocketException((int)SocketError.NotConnected);
            }

            // Lengths don't match.
            if (bytes != metaBuffer.Length)
            {
                throw new Exception("Not enough metadata");
            }
            logger.Log($"Got meta buffer - [{string.Join(",", metaBuffer)}]", LoggerState.Debug);

            // Split
            byte[] nameBuffer = subArray(metaBuffer, 0, NameBufferSize);
            byte[] sizeBuffer = subArray(metaBuffer, NameBufferSize, metaBuffer.Length);

            // Clean nameBuffer, first 'non-blank' element.
            int nonZeroIndex = 0;

            for (int i = 0; i < nameBuffer.Length; i++)
            {
                if (nameBuffer[i] < 32)  // If its not a letter (ASCII)
                {
                    nonZeroIndex = i;
                    break;
                }
            }
            Array.Resize(ref nameBuffer, nonZeroIndex);

            // Parse
            logger.Log($"Got size buffer [{string.Join(",", sizeBuffer)}]", LoggerState.Debug);
            BigInteger number = Base255.ToBigInt(sizeBuffer);

            logger.Log("Parsed as " + number, LoggerState.Debug);
            string name = System.Text.Encoding.UTF8.GetString(nameBuffer);

            client.ReceiveBufferSize = clientBufferSize;

            return(new Meta(name, number));
        }
Beispiel #3
0
        public static void SendSecure(Socket client, Meta meta, Stream data, byte[] encryptionKey)
        {
            SendMeta(client, meta);

            AesGcm gcm = new AesGcm(encryptionKey);

            byte[] buffer           = new byte[FileBufferSize];
            int    clientSendBuffer = client.SendBufferSize;

            client.SendBufferSize = FileBufferSize + TagBufferSize;

            BigInteger count = 0;

            for (BigInteger i = 0; count != meta.Size; i++)
            {
                int bytes = data.Read(buffer, 0, buffer.Length);
                count += bytes;
                logger.Log($"[{i}] Count: {count}", LoggerState.Debug);
                if (bytes != buffer.Length)
                {
                    Array.Resize(ref buffer, bytes);
                }

                byte[] tag        = new byte[16];
                byte[] cyphertext = new byte[buffer.Length];

                byte[] nonce = Base255.ToByteArr(i, NonceBufferSize);

                gcm.Encrypt(nonce, buffer, cyphertext, tag);
                logger.Log($"Cypher: {string.Join(',', cyphertext)}", LoggerState.Debug);
                logger.Log($"Tag: {string.Join(',', tag)}", LoggerState.Debug);
                logger.Log($"Nonce: {string.Join(',', nonce)}", LoggerState.Debug);

                byte[] unifiedEnc = new byte[cyphertext.Length + tag.Length];
                cyphertext.CopyTo(unifiedEnc, 0);
                tag.CopyTo(unifiedEnc, cyphertext.Length);

                client.Send(unifiedEnc, unifiedEnc.Length, SocketFlags.None);
            }
            client.SendBufferSize = clientSendBuffer;
        }
Beispiel #4
0
        /// <summary>
        /// Sends meta file structure to host via client. Check netconf.json for meta structure.
        /// </summary>
        /// <exception cref="System.Net.Sockets.SocketException">
        /// Thrown when a send operation has failed, the host has disconnected.
        /// </exception>
        public static void SendMeta(Socket client, Meta meta)
        {
            byte[] metaBuffer = new byte[MetaBufferSize];

            int clientBufferSize = client.ReceiveBufferSize;

            client.SendBufferSize = metaBuffer.Length;

            // Cap filename to NameBufferSize
            string filename = meta.Name;

            if (filename.Length > NameBufferSize)
            {
                filename = filename.Substring(0, NameBufferSize);
            }

            // Copy to the meta buffer.
            Encoding.UTF8.GetBytes(filename).CopyTo(metaBuffer, 0);

            // Copy the converted size to meta buffer.
            byte[] byteArr = Base255.ToByteArr(meta.Size);
            logger.Log($"Compressing {meta.Size} into [{string.Join(",", byteArr)}]", LoggerState.Debug);
            for (int i = 0; i < byteArr.Length; i++)
            {
                metaBuffer[(NameBufferSize) + i] = byteArr[i];
            }
            logger.Log($"Sending meta buffer - [{string.Join(",", metaBuffer)}]", LoggerState.Debug);

            // Send to client
            int bytes = client.Send(metaBuffer);

            // If no bytes received, probably disconnected.
            if (bytes == 0)
            {
                throw new SocketException((int)SocketError.NotConnected);
            }
            client.SendBufferSize = clientBufferSize;
        }